home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcl / sptmbr11.lha / clx / image.lisp < prev    next >
Lisp/Scheme  |  1992-05-19  |  102KB  |  2,669 lines

  1. ;;; -*- Mode:Lisp; Package:XLIB; Syntax:COMMON-LISP; Base:10; Lowercase:T -*-
  2.  
  3. ;;; CLX Image functions
  4.  
  5. ;;;
  6. ;;;             TEXAS INSTRUMENTS INCORPORATED
  7. ;;;                  P.O. BOX 2909
  8. ;;;                   AUSTIN, TEXAS 78769
  9. ;;;
  10. ;;; Copyright (C) 1987 Texas Instruments Incorporated.
  11. ;;;
  12. ;;; Permission is granted to any individual or institution to use, copy, modify,
  13. ;;; and distribute this software, provided that this complete copyright and
  14. ;;; permission notice is maintained, intact, in all copies and supporting
  15. ;;; documentation.
  16. ;;;
  17. ;;; Texas Instruments Incorporated provides this software "as is" without
  18. ;;; express or implied warranty.
  19. ;;;
  20.  
  21. (in-package :xlib)
  22.  
  23. (defmacro with-image-data-buffer ((buffer size) &body body)
  24.   (declare (indentation 0 4 1 1))
  25.   `(let ((.reply-buffer. (allocate-reply-buffer ,size)))
  26.      (declare (type reply-buffer .reply-buffer.))
  27.      (unwind-protect
  28.      (let ((,buffer (reply-ibuf8 .reply-buffer.)))
  29.        (declare (type buffer-bytes ,buffer))
  30.        (with-vector (,buffer buffer-bytes)
  31.          ,@body))
  32.        (deallocate-reply-buffer .reply-buffer.))))
  33.  
  34. (def-clx-class (image (:constructor nil) (:copier nil) (:predicate nil))
  35.   ;; Public structure
  36.   (width 0 :type card16 :read-only t)
  37.   (height 0 :type card16 :read-only t)
  38.   (depth 1 :type card8 :read-only t)
  39.   (plist nil :type list))
  40.  
  41. ;; Image-Plist accessors:
  42. (defmacro image-name (image) `(getf (image-plist ,image) :name))
  43. (defmacro image-x-hot (image) `(getf (image-plist ,image) :x-hot))
  44. (defmacro image-y-hot (image) `(getf (image-plist ,image) :y-hot))
  45. (defmacro image-red-mask (image) `(getf (image-plist ,image) :red-mask))
  46. (defmacro image-blue-mask (image) `(getf (image-plist ,image) :blue-mask))
  47. (defmacro image-green-mask (image) `(getf (image-plist ,image) :green-mask))
  48.  
  49. (defun print-image (image stream depth)
  50.   (declare (type image image)
  51.        (ignore depth))
  52.   (print-unreadable-object (image stream :type t)
  53.     (when (image-name image)
  54.       (write-string (string (image-name image)) stream)
  55.       (write-string " " stream))
  56.     (prin1 (image-width image) stream)
  57.     (write-string "x" stream)
  58.     (prin1 (image-height image) stream)
  59.     (write-string "x" stream)
  60.     (prin1 (image-depth image) stream)))
  61.  
  62. (defconstant *empty-data-x* '#.(make-sequence '(array card8 (*)) 0))
  63.  
  64. (defconstant *empty-data-z*
  65.          '#.(make-array '(0 0) :element-type 'pixarray-1-element-type))
  66.  
  67. (def-clx-class (image-x (:include image) (:copier nil)
  68.             (:print-function print-image))
  69.   ;; Use this format for shoveling image data
  70.   ;; Private structure. Accessors for these NOT exported.
  71.   (format :z-pixmap :type (member :bitmap :xy-pixmap :z-pixmap))
  72.   (bytes-per-line 0 :type card16)
  73.   (bits-per-pixel 1 :type (member 1 4 8 16 24 32))
  74.   (bit-lsb-first-p *image-bit-lsb-first-p* :type boolean)    ; Bit order
  75.   (byte-lsb-first-p *image-byte-lsb-first-p* :type boolean)    ; Byte order
  76.   (data *empty-data-x* :type (array card8 (*)))            ; row-major
  77.   (unit *image-unit* :type (member 8 16 32))            ; Bitmap unit
  78.   (pad *image-pad* :type (member 8 16 32))            ; Scanline pad
  79.   (left-pad 0 :type card8))                    ; Left pad
  80.  
  81. (def-clx-class (image-xy (:include image) (:copier nil)
  82.              (:print-function print-image))
  83.   ;; Public structure
  84.   ;; Use this format for image processing
  85.   (bitmap-list nil :type list)) ;; list of bitmaps
  86.  
  87. (def-clx-class (image-z (:include image) (:copier nil)
  88.             (:print-function print-image))
  89.   ;; Public structure
  90.   ;; Use this format for image processing
  91.   (bits-per-pixel 1 :type (member 1 4 8 16 24 32))
  92.   (pixarray *empty-data-z* :type pixarray))
  93.  
  94. (defun create-image (&key width height depth
  95.              (data (required-arg data))
  96.              plist name x-hot y-hot
  97.              red-mask blue-mask green-mask
  98.              bits-per-pixel format bytes-per-line
  99.              (byte-lsb-first-p 
  100.                #+clx-little-endian t
  101.                #-clx-little-endian nil)
  102.              (bit-lsb-first-p
  103.                #+clx-little-endian t
  104.                #-clx-little-endian nil)
  105.              unit pad left-pad)
  106.   ;; Returns an image-x image-xy or image-z structure, depending on the
  107.   ;; type of the :DATA parameter.
  108.   (declare
  109.     (type (or null card16) width height)    ; Required
  110.     (type (or null card8) depth)        ; Defualts to 1
  111.     (type (or buffer-bytes            ; Returns image-x
  112.           list                ; Returns image-xy
  113.           pixarray) data)            ; Returns image-z
  114.     (type list plist)
  115.     (type (or null stringable) name)
  116.     (type (or null card16) x-hot y-hot)
  117.     (type (or null pixel) red-mask blue-mask green-mask)
  118.     (type (or null (member 1 4 8 16 24 32)) bits-per-pixel)
  119.     
  120.     ;; The following parameters are ignored for image-xy and image-z:
  121.     (type (or null (member :bitmap :xy-pixmap :z-pixmap))
  122.       format)                ; defaults to :z-pixmap
  123.     (type (or null card16) bytes-per-line)
  124.     (type boolean byte-lsb-first-p bit-lsb-first-p)
  125.     (type (or null (member 8 16 32)) unit pad)
  126.     (type (or null card8) left-pad))
  127.   (declare (values image))
  128.   (let ((image
  129.       (etypecase data
  130.         (buffer-bytes            ; image-x
  131.           (let ((data data))
  132.         (declare (type buffer-bytes data))
  133.         (unless depth (setq depth (or bits-per-pixel 1)))
  134.         (unless format
  135.           (setq format (if (= depth 1) :xy-pixmap :z-pixmap)))
  136.         (unless bits-per-pixel
  137.           (setq bits-per-pixel
  138.             (cond ((eq format :xy-pixmap) 1)
  139.                   ((index> depth 24) 32)
  140.                   ((index> depth 16) 24)
  141.                   ((index> depth 8)  16)
  142.                   ((index> depth 4)   8)
  143.                   ((index> depth 1)   4)
  144.                   (t                  1))))
  145.         (unless width (required-arg width))
  146.         (unless height (required-arg height))
  147.         (unless bytes-per-line
  148.           (let* ((pad (or pad 8))
  149.              (bits-per-line (index* width bits-per-pixel))
  150.              (padded-bits-per-line
  151.                (index* (index-ceiling bits-per-line pad) pad)))
  152.             (declare (type array-index pad bits-per-line
  153.                    padded-bits-per-line))
  154.             (setq bytes-per-line (index-ceiling padded-bits-per-line 8))))
  155.         (unless unit (setq unit *image-unit*))
  156.         (unless pad
  157.           (setq pad
  158.             (dolist (pad '(32 16 8))
  159.               (when (and (index<= pad *image-pad*)
  160.                      (zerop
  161.                        (index-mod
  162.                      (index* bytes-per-line 8) pad)))
  163.                 (return pad)))))
  164.         (unless left-pad (setq left-pad 0))
  165.         (make-image-x
  166.           :width width :height height :depth depth :plist plist
  167.           :format format :data data
  168.           :bits-per-pixel bits-per-pixel 
  169.           :bytes-per-line bytes-per-line
  170.           :byte-lsb-first-p byte-lsb-first-p
  171.           :bit-lsb-first-p bit-lsb-first-p
  172.           :unit unit :pad pad :left-pad left-pad)))
  173.         (list                ; image-xy
  174.           (let ((data data))
  175.         (declare (type list data))
  176.         (unless depth (setq depth (length data)))
  177.         (when data
  178.           (unless width (setq width (array-dimension (car data) 1)))
  179.           (unless height (setq height (array-dimension (car data) 0))))
  180.         (make-image-xy
  181.           :width width :height height :plist plist :depth depth
  182.           :bitmap-list data)))
  183.         (pixarray                ; image-z
  184.           (let ((data data))
  185.         (declare (type pixarray data))
  186.         (unless width (setq width (array-dimension data 1)))
  187.         (unless height (setq height (array-dimension data 0)))
  188.         (unless bits-per-pixel
  189.           (setq bits-per-pixel
  190.             (etypecase data
  191.               (pixarray-32 32)
  192.               (pixarray-24 24)
  193.               (pixarray-16 16)
  194.               (pixarray-8   8)
  195.               (pixarray-4   4)
  196.               (pixarray-1   1)))))
  197.           (unless depth (setq depth bits-per-pixel))
  198.           (make-image-z
  199.         :width width :height height :depth depth :plist plist
  200.         :bits-per-pixel bits-per-pixel :pixarray data)))))
  201.     (declare (type image image))
  202.     (when name (setf (image-name image) name))
  203.     (when x-hot (setf (image-x-hot image) x-hot))
  204.     (when y-hot (setf (image-y-hot image) y-hot))
  205.     (when red-mask (setf (image-red-mask image) red-mask))
  206.     (when blue-mask (setf (image-blue-mask image) blue-mask))
  207.     (when green-mask (setf (image-green-mask image) green-mask))
  208.     image))
  209.  
  210. ;;;-----------------------------------------------------------------------------
  211. ;;; Swapping stuff
  212.  
  213. (defun image-noswap
  214.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  215.   (declare (type buffer-bytes src dest)
  216.        (type array-index srcoff destoff srclen srcinc destinc)
  217.        (type card16 height)
  218.        (type boolean lsb-first-p)
  219.        (ignore lsb-first-p))
  220.   #.(declare-buffun)
  221.   (if (index= srcinc destinc)
  222.       (buffer-replace
  223.     dest src destoff
  224.     (index+ destoff (index* srcinc (index1- height)) srclen)
  225.     srcoff)
  226.     (do* ((h height (index1- h))
  227.       (srcstart srcoff (index+ srcstart srcinc))
  228.       (deststart destoff (index+ deststart destinc))
  229.       (destend (index+ deststart srclen) (index+ deststart srclen)))
  230.      ((index-zerop h))
  231.       (declare (type array-index srcstart deststart destend)
  232.            (type card16 h))
  233.       (buffer-replace dest src deststart destend srcstart))))
  234.  
  235. (defun image-swap-two-bytes
  236.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  237.   (declare (type buffer-bytes src dest)
  238.        (type array-index srcoff destoff srclen srcinc destinc)
  239.        (type card16 height)
  240.        (type boolean lsb-first-p))
  241.   #.(declare-buffun)
  242.   (with-vector (src buffer-bytes)
  243.     (with-vector (dest buffer-bytes)
  244.       (do ((length (index* (index-ceiling srclen 2) 2))
  245.        (h height (index1- h))
  246.        (srcstart srcoff (index+ srcstart srcinc))
  247.        (deststart destoff (index+ deststart destinc)))
  248.       ((index-zerop h))
  249.     (declare (type array-index length srcstart deststart)
  250.          (type card16 h))
  251.     (when (and (index= h 1) (not (index= srclen length)))
  252.       (index-decf length 2)
  253.       (if lsb-first-p
  254.           (setf (aref dest (index1+ (index+ deststart length)))
  255.             (the card8 (aref src (index+ srcstart length))))
  256.         (setf (aref dest (index+ deststart length))
  257.           (the card8 (aref src (index1+ (index+ srcstart length)))))))
  258.     (do ((i length (index- i 2))
  259.          (srcidx srcstart (index+ srcidx 2))
  260.          (destidx deststart (index+ destidx 2)))
  261.         ((index-zerop i))
  262.       (declare (type array-index i srcidx destidx))
  263.       (setf (aref dest destidx)
  264.         (the card8 (aref src (index1+ srcidx))))
  265.       (setf (aref dest (index1+ destidx))
  266.         (the card8 (aref src srcidx))))))))
  267.  
  268. (defun image-swap-three-bytes
  269.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  270.   (declare (type buffer-bytes src dest)
  271.        (type array-index srcoff destoff srclen srcinc destinc)
  272.        (type card16 height)
  273.        (type boolean lsb-first-p))
  274.   #.(declare-buffun)
  275.   (with-vector (src buffer-bytes)
  276.     (with-vector (dest buffer-bytes)
  277.       (do ((length (index* (index-ceiling srclen 3) 3))
  278.        (h height (index1- h))
  279.        (srcstart srcoff (index+ srcstart srcinc))
  280.        (deststart destoff (index+ deststart destinc)))
  281.       ((index-zerop h))
  282.     (declare (type array-index length srcstart deststart)
  283.          (type card16 h))
  284.     (when (and (index= h 1) (not (index= srclen length)))
  285.       (index-decf length 3)
  286.       (when (index= (index- srclen length) 2)
  287.         (setf (aref dest (index+ deststart length 1))
  288.           (the card8 (aref src (index+ srcstart length 1)))))
  289.       (if lsb-first-p
  290.           (setf (aref dest (index+ deststart length 2))
  291.             (the card8 (aref src (index+ srcstart length))))
  292.         (setf (aref dest (index+ deststart length))
  293.           (the card8 (aref src (index+ srcstart length 2))))))
  294.     (do ((i length (index- i 3))
  295.          (srcidx srcstart (index+ srcidx 3))
  296.          (destidx deststart (index+ destidx 3)))
  297.         ((index-zerop i))
  298.       (declare (type array-index i srcidx destidx))
  299.       (setf (aref dest destidx)
  300.         (the card8 (aref src (index+ srcidx 2))))
  301.       (setf (aref dest (index1+ destidx))
  302.         (the card8 (aref src (index1+ srcidx))))
  303.       (setf (aref dest (index+ destidx 2))
  304.         (the card8 (aref src srcidx))))))))
  305.  
  306. (defun image-swap-four-bytes
  307.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  308.   (declare (type buffer-bytes src dest)
  309.        (type array-index srcoff destoff srclen srcinc destinc)
  310.        (type card16 height)
  311.        (type boolean lsb-first-p))
  312.   #.(declare-buffun)
  313.   (with-vector (src buffer-bytes)
  314.     (with-vector (dest buffer-bytes)
  315.       (do ((length (index* (index-ceiling srclen 4) 4))
  316.        (h height (index1- h))
  317.        (srcstart srcoff (index+ srcstart srcinc))
  318.        (deststart destoff (index+ deststart destinc)))
  319.       ((index-zerop h))
  320.     (declare (type array-index length srcstart deststart)
  321.          (type card16 h))
  322.     (when (and (index= h 1) (not (index= srclen length)))
  323.       (index-decf length 4)
  324.       (unless lsb-first-p
  325.         (setf (aref dest (index+ deststart length))
  326.           (the card8 (aref src (index+ srcstart length 3)))))
  327.       (when (if lsb-first-p
  328.             (index= (index- srclen length) 3)
  329.           (not (index-zerop (index-logand srclen 2))))
  330.         (setf (aref dest (index+ deststart length 1))
  331.           (the card8 (aref src (index+ srcstart length 2)))))
  332.       (when (if (null lsb-first-p)
  333.             (index= (index- srclen length) 3)
  334.           (not (index-zerop (index-logand srclen 2))))
  335.         (setf (aref dest (index+ deststart length 2))
  336.           (the card8 (aref src (index+ srcstart length 1)))))
  337.       (when lsb-first-p
  338.         (setf (aref dest (index+ deststart length 3))
  339.           (the card8 (aref src (index+ srcstart length))))))
  340.     (do ((i length (index- i 4))
  341.          (srcidx srcstart (index+ srcidx 4))
  342.          (destidx deststart (index+ destidx 4)))
  343.         ((index-zerop i))
  344.       (declare (type array-index i srcidx destidx))
  345.       (setf (aref dest destidx)
  346.         (the card8 (aref src (index+ srcidx 3))))
  347.       (setf (aref dest (index1+ destidx))
  348.         (the card8 (aref src (index+ srcidx 2))))
  349.       (setf (aref dest (index+ destidx 2))
  350.         (the card8 (aref src (index1+ srcidx))))
  351.       (setf (aref dest (index+ destidx 3))
  352.         (the card8 (aref src srcidx))))))))
  353.  
  354. (defun image-swap-words
  355.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  356.   (declare (type buffer-bytes src dest)
  357.        (type array-index srcoff destoff srclen srcinc destinc)
  358.        (type card16 height)
  359.        (type boolean lsb-first-p))
  360.   #.(declare-buffun)
  361.   (with-vector (src buffer-bytes)
  362.     (with-vector (dest buffer-bytes)
  363.       (do ((length (index* (index-ceiling srclen 4) 4))
  364.        (h height (index1- h))
  365.        (srcstart srcoff (index+ srcstart srcinc))
  366.        (deststart destoff (index+ deststart destinc)))
  367.       ((index-zerop h))
  368.     (declare (type array-index length srcstart deststart)
  369.          (type card16 h))
  370.     (when (and (index= h 1) (not (index= srclen length)))
  371.       (index-decf length 4)
  372.       (unless lsb-first-p
  373.         (setf (aref dest (index+ deststart length 1))
  374.           (the card8 (aref src (index+ srcstart length 3)))))
  375.       (when (if lsb-first-p
  376.             (index= (index- srclen length) 3)
  377.           (not (index-zerop (index-logand srclen 2))))
  378.         (setf (aref dest (index+ deststart length))
  379.           (the card8 (aref src (index+ srcstart length 2)))))
  380.       (when (if (null lsb-first-p)
  381.             (index= (index- srclen length) 3)
  382.           (not (index-zerop (index-logand srclen 2))))
  383.         (setf (aref dest (index+ deststart length 3))
  384.           (the card8 (aref src (index+ srcstart length 1)))))
  385.       (when lsb-first-p
  386.         (setf (aref dest (index+ deststart length 2))
  387.           (the card8 (aref src (index+ srcstart length))))))
  388.     (do ((i length (index- i 4))
  389.          (srcidx srcstart (index+ srcidx 4))
  390.          (destidx deststart (index+ destidx 4)))
  391.         ((index-zerop i))
  392.       (declare (type array-index i srcidx destidx))
  393.       (setf (aref dest destidx)
  394.         (the card8 (aref src (index+ srcidx 2))))
  395.       (setf (aref dest (index1+ destidx))
  396.         (the card8 (aref src (index+ srcidx 3))))
  397.       (setf (aref dest (index+ destidx 2))
  398.         (the card8 (aref src srcidx)))
  399.       (setf (aref dest (index+ destidx 3))
  400.         (the card8 (aref src (index1+ srcidx)))))))))
  401.  
  402. (defun image-swap-nibbles
  403.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  404.   (declare (type buffer-bytes src dest)
  405.        (type array-index srcoff destoff srclen srcinc destinc)
  406.        (type card16 height)
  407.        (type boolean lsb-first-p)
  408.        (ignore lsb-first-p))
  409.   #.(declare-buffun)
  410.   (with-vector (src buffer-bytes)
  411.     (with-vector (dest buffer-bytes)
  412.       (do ((h height (index1- h))
  413.        (srcstart srcoff (index+ srcstart srcinc))
  414.        (deststart destoff (index+ deststart destinc)))
  415.       ((index-zerop h))
  416.     (declare (type array-index srcstart deststart)
  417.          (type card16 h))
  418.     (do ((i srclen (index1- i))
  419.          (srcidx srcstart (index1+ srcidx))
  420.          (destidx deststart (index1+ destidx)))
  421.         ((index-zerop i))
  422.       (declare (type array-index i srcidx destidx))
  423.       (setf (aref dest destidx)
  424.         (the card8
  425.              (let ((byte (aref src srcidx)))
  426.                (declare (type card8 byte))
  427.                (dpb (the card4 (ldb (byte 4 0) byte))
  428.                 (byte 4 4)
  429.                 (the card4 (ldb (byte 4 4) byte)))))))))))
  430.  
  431. (defun image-swap-nibbles-left
  432.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  433.   (declare (type buffer-bytes src dest)
  434.        (type array-index srcoff destoff srclen srcinc destinc)
  435.        (type card16 height)
  436.        (type boolean lsb-first-p)
  437.        (ignore lsb-first-p))
  438.   #.(declare-buffun)
  439.   (with-vector (src buffer-bytes)
  440.     (with-vector (dest buffer-bytes)
  441.       (do ((h height (index1- h))
  442.        (srcstart srcoff (index+ srcstart srcinc))
  443.        (deststart destoff (index+ deststart destinc)))
  444.       ((index-zerop h))
  445.     (declare (type array-index srcstart deststart)
  446.          (type card16 h))
  447.     (do ((i srclen (index1- i))
  448.          (srcidx srcstart (index1+ srcidx))
  449.          (destidx deststart (index1+ destidx)))
  450.         ((index= i 1)
  451.          (setf (aref dest destidx)
  452.            (the card8
  453.             (let ((byte1 (aref src srcidx)))
  454.               (declare (type card8 byte1))
  455.               (dpb (the card4 (ldb (byte 4 0) byte1))
  456.                    (byte 4 4)
  457.                    0)))))
  458.       (declare (type array-index i srcidx destidx))
  459.       (setf (aref dest destidx)
  460.         (the card8
  461.              (let ((byte1 (aref src srcidx))
  462.                (byte2 (aref src (index1+ srcidx))))
  463.                (declare (type card8 byte1 byte2))
  464.                (dpb (the card4 (ldb (byte 4 0) byte1))
  465.                 (byte 4 4)
  466.                 (the card4 (ldb (byte 4 4) byte2)))))))))))
  467.  
  468. (defconstant
  469.   *image-byte-reverse*
  470.   '#.(coerce
  471.        '#(
  472.       0 128 64 192 32 160 96 224 16 144 80 208 48 176 112 240
  473.       8 136 72 200 40 168 104 232 24 152 88 216 56 184 120 248
  474.       4 132 68 196 36 164 100 228 20 148 84 212 52 180 116 244
  475.       12 140 76 204 44 172 108 236 28 156 92 220 60 188 124 252
  476.       2 130 66 194 34 162 98 226 18 146 82 210 50 178 114 242
  477.       10 138 74 202 42 170 106 234 26 154 90 218 58 186 122 250
  478.       6 134 70 198 38 166 102 230 22 150 86 214 54 182 118 246
  479.       14 142 78 206 46 174 110 238 30 158 94 222 62 190 126 254
  480.       1 129 65 193 33 161 97 225 17 145 81 209 49 177 113 241
  481.       9 137 73 201 41 169 105 233 25 153 89 217 57 185 121 249
  482.       5 133 69 197 37 165 101 229 21 149 85 213 53 181 117 245
  483.       13 141 77 205 45 173 109 237 29 157 93 221 61 189 125 253
  484.       3 131 67 195 35 163 99 227 19 147 83 211 51 179 115 243
  485.       11 139 75 203 43 171 107 235 27 155 91 219 59 187 123 251
  486.       7 135 71 199 39 167 103 231 23 151 87 215 55 183 119 247
  487.       15 143 79 207 47 175 111 239 31 159 95 223 63 191 127 255)
  488.        '(vector card8)))
  489.  
  490. (defun image-swap-bits
  491.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  492.   (declare (type buffer-bytes src dest)
  493.        (type array-index srcoff destoff srclen srcinc destinc)
  494.        (type card16 height)
  495.        (type boolean lsb-first-p)
  496.        (ignore lsb-first-p))
  497.   #.(declare-buffun)
  498.   (with-vector (src buffer-bytes)
  499.     (with-vector (dest buffer-bytes)
  500.       (let ((byte-reverse *image-byte-reverse*))
  501.     (with-vector (byte-reverse (simple-array card8 (256)))
  502.       (macrolet ((br (byte)
  503.                `(the card8 (aref byte-reverse (the card8 ,byte)))))
  504.         (do ((h height (index1- h))
  505.          (srcstart srcoff (index+ srcstart srcinc))
  506.          (deststart destoff (index+ deststart destinc)))
  507.         ((index-zerop h))
  508.           (declare (type array-index srcstart deststart)
  509.                (type card16 h))
  510.           (do ((i srclen (index1- i))
  511.            (srcidx srcstart (index1+ srcidx))
  512.            (destidx deststart (index1+ destidx)))
  513.           ((index-zerop i))
  514.         (declare (type array-index i srcidx destidx))
  515.         (setf (aref dest destidx) (br (aref src srcidx)))))))))))
  516.  
  517. (defun image-swap-bits-and-two-bytes
  518.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  519.   (declare (type buffer-bytes src dest)
  520.        (type array-index srcoff destoff srclen srcinc destinc)
  521.        (type card16 height)
  522.        (type boolean lsb-first-p))
  523.   #.(declare-buffun)
  524.   (with-vector (src buffer-bytes)
  525.     (with-vector (dest buffer-bytes)
  526.       (let ((byte-reverse *image-byte-reverse*))
  527.     (with-vector (byte-reverse (simple-array card8 (256)))
  528.       (macrolet ((br (byte)
  529.                `(the card8 (aref byte-reverse (the card8 ,byte)))))
  530.         (do ((length (index* (index-ceiling srclen 2) 2))
  531.          (h height (index1- h))
  532.          (srcstart srcoff (index+ srcstart srcinc))
  533.          (deststart destoff (index+ deststart destinc)))
  534.         ((index-zerop h))
  535.           (declare (type array-index length srcstart deststart)
  536.                (type card16 h))
  537.           (when (and (index= h 1) (not (index= srclen length)))
  538.         (index-decf length 2)
  539.         (if lsb-first-p
  540.             (setf (aref dest (index1+ (index+ deststart length)))
  541.               (br (aref src (index+ srcstart length))))
  542.           (setf (aref dest (index+ deststart length))
  543.             (br (aref src (index1+ (index+ srcstart length)))))))
  544.           (do ((i length (index- i 2))
  545.            (srcidx srcstart (index+ srcidx 2))
  546.            (destidx deststart (index+ destidx 2)))
  547.           ((index-zerop i))
  548.         (declare (type array-index i srcidx destidx))
  549.         (setf (aref dest destidx)
  550.               (br (aref src (index1+ srcidx))))
  551.         (setf (aref dest (index1+ destidx))
  552.               (br (aref src srcidx)))))))))))
  553.  
  554. (defun image-swap-bits-and-four-bytes
  555.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  556.   (declare (type buffer-bytes src dest)
  557.        (type array-index srcoff destoff srclen srcinc destinc)
  558.        (type card16 height)
  559.        (type boolean lsb-first-p))
  560.   #.(declare-buffun)
  561.   (with-vector (src buffer-bytes)
  562.     (with-vector (dest buffer-bytes)
  563.       (let ((byte-reverse *image-byte-reverse*))
  564.     (with-vector (byte-reverse (simple-array card8 (256)))
  565.       (macrolet ((br (byte)
  566.                `(the card8 (aref byte-reverse (the card8 ,byte)))))
  567.         (do ((length (index* (index-ceiling srclen 4) 4))
  568.          (h height (index1- h))
  569.          (srcstart srcoff (index+ srcstart srcinc))
  570.          (deststart destoff (index+ deststart destinc)))
  571.         ((index-zerop h))
  572.           (declare (type array-index length srcstart deststart)
  573.                (type card16 h))
  574.           (when (and (index= h 1) (not (index= srclen length)))
  575.         (index-decf length 4)
  576.         (unless lsb-first-p
  577.           (setf (aref dest (index+ deststart length))
  578.             (br (aref src (index+ srcstart length 3)))))
  579.         (when (if lsb-first-p
  580.               (index= (index- srclen length) 3)
  581.             (not (index-zerop (index-logand srclen 2))))
  582.           (setf (aref dest (index+ deststart length 1))
  583.             (br (aref src (index+ srcstart length 2)))))
  584.         (when (if (null lsb-first-p)
  585.               (index= (index- srclen length) 3)
  586.             (not (index-zerop (index-logand srclen 2))))
  587.           (setf (aref dest (index+ deststart length 2))
  588.             (br (aref src (index+ srcstart length 1)))))
  589.         (when lsb-first-p
  590.           (setf (aref dest (index+ deststart length 3))
  591.             (br (aref src (index+ srcstart length))))))
  592.           (do ((i length (index- i 4))
  593.            (srcidx srcstart (index+ srcidx 4))
  594.            (destidx deststart (index+ destidx 4)))
  595.           ((index-zerop i))
  596.         (declare (type array-index i srcidx destidx))
  597.         (setf (aref dest destidx)
  598.               (br (aref src (index+ srcidx 3))))
  599.         (setf (aref dest (index1+ destidx))
  600.               (br (aref src (index+ srcidx 2))))
  601.         (setf (aref dest (index+ destidx 2))
  602.               (br (aref src (index1+ srcidx))))
  603.         (setf (aref dest (index+ destidx 3))
  604.               (br (aref src srcidx)))))))))))
  605.  
  606. (defun image-swap-bits-and-words
  607.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  608.   (declare (type buffer-bytes src dest)
  609.        (type array-index srcoff destoff srclen srcinc destinc)
  610.        (type card16 height)
  611.        (type boolean lsb-first-p))
  612.   #.(declare-buffun)
  613.   (with-vector (src buffer-bytes)
  614.     (with-vector (dest buffer-bytes)
  615.       (let ((byte-reverse *image-byte-reverse*))
  616.     (with-vector (byte-reverse (simple-array card8 (256)))
  617.       (macrolet ((br (byte)
  618.                `(the card8 (aref byte-reverse (the card8 ,byte)))))
  619.         (do ((length (index* (index-ceiling srclen 4) 4))
  620.          (h height (index1- h))
  621.          (srcstart srcoff (index+ srcstart srcinc))
  622.          (deststart destoff (index+ deststart destinc)))
  623.         ((index-zerop h))
  624.           (declare (type array-index length srcstart deststart)
  625.                (type card16 h))
  626.           (when (and (index= h 1) (not (index= srclen length)))
  627.         (index-decf length 4)
  628.         (unless lsb-first-p
  629.           (setf (aref dest (index+ deststart length 1))
  630.             (br (aref src (index+ srcstart length 3)))))
  631.         (when (if lsb-first-p
  632.               (index= (index- srclen length) 3)
  633.             (not (index-zerop (index-logand srclen 2))))
  634.           (setf (aref dest (index+ deststart length))
  635.             (br (aref src (index+ srcstart length 2)))))
  636.         (when (if (null lsb-first-p)
  637.               (index= (index- srclen length) 3)
  638.             (not (index-zerop (index-logand srclen 2))))
  639.           (setf (aref dest (index+ deststart length 3))
  640.             (br (aref src (index+ srcstart length 1)))))
  641.         (when lsb-first-p
  642.           (setf (aref dest (index+ deststart length 2))
  643.             (br (aref src (index+ srcstart length))))))
  644.           (do ((i length (index- i 4))
  645.            (srcidx srcstart (index+ srcidx 4))
  646.            (destidx deststart (index+ destidx 4)))
  647.           ((index-zerop i))
  648.         (declare (type array-index i srcidx destidx))
  649.         (setf (aref dest destidx)
  650.               (br (aref src (index+ srcidx 2))))
  651.         (setf (aref dest (index1+ destidx))
  652.               (br (aref src (index+ srcidx 3))))
  653.         (setf (aref dest (index+ destidx 2))
  654.               (br (aref src srcidx)))
  655.         (setf (aref dest (index+ destidx 3))
  656.               (br (aref src (index1+ srcidx))))))))))))
  657.  
  658. ;;; The following table gives the bit ordering within bytes (when accessed
  659. ;;; sequentially) for a scanline containing 32 bits, with bits numbered 0 to
  660. ;;; 31, where bit 0 should be leftmost on the display.  For a given byte
  661. ;;; labelled A-B, A is for the most significant bit of the byte, and B is
  662. ;;; for the least significant bit.
  663. ;;; 
  664. ;;; legend:
  665. ;;;     1   scanline-unit = 8
  666. ;;;     2   scanline-unit = 16
  667. ;;;     4   scanline-unit = 32
  668. ;;;     M   byte-order = MostSignificant
  669. ;;;     L   byte-order = LeastSignificant
  670. ;;;     m   bit-order = MostSignificant
  671. ;;;     l   bit-order = LeastSignificant
  672. ;;; 
  673. ;;; 
  674. ;;; format    ordering
  675. ;;; 
  676. ;;; 1Mm    00-07 08-15 16-23 24-31
  677. ;;; 2Mm    00-07 08-15 16-23 24-31
  678. ;;; 4Mm    00-07 08-15 16-23 24-31
  679. ;;; 1Ml    07-00 15-08 23-16 31-24
  680. ;;; 2Ml    15-08 07-00 31-24 23-16
  681. ;;; 4Ml    31-24 23-16 15-08 07-00
  682. ;;; 1Lm    00-07 08-15 16-23 24-31
  683. ;;; 2Lm    08-15 00-07 24-31 16-23
  684. ;;; 4Lm    24-31 16-23 08-15 00-07
  685. ;;; 1Ll    07-00 15-08 23-16 31-24
  686. ;;; 2Ll    07-00 15-08 23-16 31-24
  687. ;;; 4Ll    07-00 15-08 23-16 31-24
  688. ;;; 
  689. ;;; 
  690. ;;; The following table gives the required conversion between any two
  691. ;;; formats.  It is based strictly on the table above.  If you believe one,
  692. ;;; you should believe the other.
  693. ;;; 
  694. ;;; legend:
  695. ;;;     n   no changes
  696. ;;;     s   reverse 8-bit units within 16-bit units
  697. ;;;     l   reverse 8-bit units within 32-bit units
  698. ;;;     w   reverse 16-bit units within 32-bit units
  699. ;;;     r   reverse bits within 8-bit units
  700. ;;;     sr  s+R
  701. ;;;     lr  l+R
  702. ;;;     wr  w+R
  703.  
  704. (defconstant 
  705.   *image-swap-function*
  706.   '#.(make-array
  707.        '(12 12) :initial-contents
  708.        (let ((n  'image-noswap)
  709.          (s  'image-swap-two-bytes)
  710.          (l  'image-swap-four-bytes)
  711.          (w  'image-swap-words)
  712.          (r  'image-swap-bits)
  713.          (sr 'image-swap-bits-and-two-bytes)
  714.          (lr 'image-swap-bits-and-four-bytes)
  715.          (wr 'image-swap-bits-and-words))
  716.      (list #|             1Mm 2Mm 4Mm 1Ml 2Ml 4Ml 1Lm 2Lm 4Lm 1Ll 2Ll 4Ll  |#
  717.            (list #| 1Mm |# n   n   n   r   sr  lr  n   s   l   r   r   r )
  718.            (list #| 2Mm |# n   n   n   r   sr  lr  n   s   l   r   r   r )
  719.            (list #| 4Mm |# n   n   n   r   sr  lr  n   s   l   r   r   r )
  720.            (list #| 1Ml |# r   r   r   n   s   l   r   sr  lr  n   n   n )
  721.            (list #| 2Ml |# sr  sr  sr  s   n   w   sr  r   wr  s   s   s )
  722.            (list #| 4Ml |# lr  lr  lr  l   w   n   lr  wr  r   l   l   l )
  723.            (list #| 1Lm |# n   n   n   r   sr  lr  n   s   l   r   r   r )
  724.            (list #| 2Lm |# s   s   s   sr  r   wr  s   n   w   sr  sr  sr)
  725.            (list #| 4Lm |# l   l   l   lr  wr  r   l   w   n   lr  lr  lr)
  726.            (list #| 1Ll |# r   r   r   n   s   l   r   sr  lr  n   n   n )
  727.            (list #| 2Ll |# r   r   r   n   s   l   r   sr  lr  n   n   n )
  728.            (list #| 4Ll |# r   r   r   n   s   l   r   sr  lr  n   n   n )))))
  729.  
  730. ;;; Of course, the table above is a lie.  We also need to factor in the
  731. ;;; order of the source data to cope with swapping half of a unit at the
  732. ;;; end of a scanline, since we are trying to avoid de-ref'ing off the
  733. ;;; end of the source.
  734. ;;;
  735. ;;; Defines whether the first half of a unit has the first half of the data
  736.  
  737. (defconstant
  738.   *image-swap-lsb-first-p*
  739.   '#.(make-array
  740.        12 :initial-contents
  741.        (list t   #| 1mm |#
  742.          t   #| 2mm |#
  743.          t   #| 4mm |#
  744.          t   #| 1ml |#
  745.          nil #| 2ml |#
  746.          nil #| 4ml |#
  747.          t   #| 1lm |#
  748.          nil #| 2lm |#
  749.          nil #| 4lm |#
  750.          t   #| 1ll |#
  751.          t   #| 2ll |#
  752.          t   #| 4ll |#
  753.          )))
  754.  
  755. (defun image-swap-function
  756.        (bits-per-pixel
  757.     from-bitmap-unit from-byte-lsb-first-p from-bit-lsb-first-p
  758.     to-bitmap-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  759.   (declare (type (member 1 4 8 16 24 32) bits-per-pixel)
  760.        (type (member 8 16 32) from-bitmap-unit to-bitmap-unit)
  761.        (type boolean from-byte-lsb-first-p from-bit-lsb-first-p
  762.          to-byte-lsb-first-p to-bit-lsb-first-p)
  763.        (values function lsb-first-p))
  764.   (cond ((index= bits-per-pixel 1)
  765.      (let ((from-index
  766.          (index+
  767.            (ecase from-bitmap-unit (32 2) (16 1) (8 0))
  768.            (if from-bit-lsb-first-p 3 0)
  769.            (if from-byte-lsb-first-p 6 0))))
  770.        (values
  771.          (aref *image-swap-function* from-index
  772.            (index+
  773.              (ecase to-bitmap-unit (32 2) (16 1) (8 0))
  774.              (if to-bit-lsb-first-p 3 0)
  775.              (if to-byte-lsb-first-p 6 0)))
  776.          (aref *image-swap-lsb-first-p* from-index))))
  777.     (t
  778.      (values 
  779.        (if (if (index= bits-per-pixel 4)
  780.            (eq from-bit-lsb-first-p to-bit-lsb-first-p)
  781.          (eq from-byte-lsb-first-p to-byte-lsb-first-p))
  782.            'image-noswap
  783.          (ecase bits-per-pixel
  784.            (4  'image-swap-nibbles)
  785.            (8  'image-noswap)
  786.            (16 'image-swap-two-bytes)
  787.            (24 'image-swap-three-bytes)
  788.            (32 'image-swap-four-bytes)))
  789.        from-byte-lsb-first-p))))
  790.  
  791.  
  792. ;;;-----------------------------------------------------------------------------
  793. ;;; GET-IMAGE
  794.  
  795. (defun read-pixarray-1 (buffer-bbuf index array x y width height  
  796.             padded-bytes-per-line bits-per-pixel)
  797.   (declare (type buffer-bytes buffer-bbuf)
  798.        (type pixarray-1 array)
  799.        (type card16 x y width height)
  800.        (type array-index index padded-bytes-per-line)
  801.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  802.        (ignore bits-per-pixel))
  803.   #.(declare-buffun)
  804.   (with-vector (buffer-bbuf buffer-bytes)
  805.     (do* ((start (index+ index
  806.              (index* y padded-bytes-per-line)
  807.              (index-ceiling x 8))
  808.          (index+ start padded-bytes-per-line))
  809.       (y 0 (index1+ y))
  810.       (left-bits (the array-index
  811.               (mod (the (integer #x-FFFF 0) (- x))
  812.                    8)))
  813.       (right-bits (index-mod (index- width left-bits) 8))
  814.       (middle-bits (index- width left-bits right-bits))
  815.       (middle-bytes (index-floor middle-bits 8)))
  816.      ((index>= y height))
  817.       (declare (type array-index start y
  818.              left-bits right-bits middle-bits middle-bytes))
  819.       (cond ((index< middle-bits 0)
  820.          (let ((byte (aref buffer-bbuf (index1- start)))
  821.            (x left-bits))
  822.            (declare (type card8 byte)
  823.             (type array-index x))
  824.            (when (index> right-bits 6)
  825.          (setf (aref array y (index- x 1))
  826.                (read-image-load-byte 1 7 byte)))
  827.            (when (and (index> left-bits 1)
  828.               (index> right-bits 5))
  829.          (setf (aref array y (index- x 2))
  830.                (read-image-load-byte 1 6 byte)))
  831.            (when (and (index> left-bits 2)
  832.               (index> right-bits 4))
  833.          (setf (aref array y (index- x 3))
  834.                (read-image-load-byte 1 5 byte)))
  835.            (when (and (index> left-bits 3)
  836.               (index> right-bits 3))
  837.          (setf (aref array y (index- x 4))
  838.                (read-image-load-byte 1 4 byte)))
  839.            (when (and (index> left-bits 4)
  840.               (index> right-bits 2))
  841.          (setf (aref array y (index- x 5))
  842.                (read-image-load-byte 1 3 byte)))
  843.            (when (and (index> left-bits 5)
  844.               (index> right-bits 1))
  845.          (setf (aref array y (index- x 6))
  846.                (read-image-load-byte 1 2 byte)))
  847.            (when (index> left-bits 6)
  848.          (setf (aref array y (index- x 7))
  849.                (read-image-load-byte 1 1 byte)))))
  850.         (t
  851.          (unless (index-zerop left-bits)
  852.            (let ((byte (aref buffer-bbuf (index1- start)))
  853.              (x left-bits))
  854.          (declare (type card8 byte)
  855.               (type array-index x))
  856.          (setf (aref array y (index- x 1))
  857.                (read-image-load-byte 1 7 byte))
  858.          (when (index> left-bits 1)
  859.            (setf (aref array y (index- x 2))
  860.              (read-image-load-byte 1 6 byte))
  861.            (when (index> left-bits 2)
  862.              (setf (aref array y (index- x 3))
  863.                (read-image-load-byte 1 5 byte))
  864.              (when (index> left-bits 3)
  865.                (setf (aref array y (index- x 4))
  866.                  (read-image-load-byte 1 4 byte))
  867.                (when (index> left-bits 4)
  868.              (setf (aref array y (index- x 5))
  869.                    (read-image-load-byte 1 3 byte))
  870.              (when (index> left-bits 5)
  871.                (setf (aref array y (index- x 6))
  872.                  (read-image-load-byte 1 2 byte))
  873.                (when (index> left-bits 6)
  874.                  (setf (aref array y (index- x 7))
  875.                    (read-image-load-byte 1 1 byte))
  876.                  ))))))))
  877.          (do* ((end (index+ start middle-bytes))
  878.            (i start (index1+ i))
  879.            (x left-bits (index+ x 8)))
  880.           ((index>= i end)
  881.            (unless (index-zerop right-bits)
  882.              (let ((byte (aref buffer-bbuf end))
  883.                (x (index+ left-bits middle-bits)))
  884.                (declare (type card8 byte)
  885.                 (type array-index x))
  886.                (setf (aref array y (index+ x 0))
  887.                  (read-image-load-byte 1 0 byte))
  888.                (when (index> right-bits 1)
  889.              (setf (aref array y (index+ x 1))
  890.                    (read-image-load-byte 1 1 byte))
  891.              (when (index> right-bits 2)
  892.                (setf (aref array y (index+ x 2))
  893.                  (read-image-load-byte 1 2 byte))
  894.                (when (index> right-bits 3)
  895.                  (setf (aref array y (index+ x 3))
  896.                    (read-image-load-byte 1 3 byte))
  897.                  (when (index> right-bits 4)
  898.                    (setf (aref array y (index+ x 4))
  899.                      (read-image-load-byte 1 4 byte))
  900.                    (when (index> right-bits 5)
  901.                  (setf (aref array y (index+ x 5))
  902.                        (read-image-load-byte 1 5 byte))
  903.                  (when (index> right-bits 6)
  904.                    (setf (aref array y (index+ x 6))
  905.                      (read-image-load-byte 1 6 byte))
  906.                    )))))))))
  907.            (declare (type array-index end i x))
  908.            (let ((byte (aref buffer-bbuf i)))
  909.          (declare (type card8 byte))
  910.          (setf (aref array y (index+ x 0))
  911.                (read-image-load-byte 1 0 byte))
  912.          (setf (aref array y (index+ x 1))
  913.                (read-image-load-byte 1 1 byte))
  914.          (setf (aref array y (index+ x 2))
  915.                (read-image-load-byte 1 2 byte))
  916.          (setf (aref array y (index+ x 3))
  917.                (read-image-load-byte 1 3 byte))
  918.          (setf (aref array y (index+ x 4))
  919.                (read-image-load-byte 1 4 byte))
  920.          (setf (aref array y (index+ x 5))
  921.                (read-image-load-byte 1 5 byte))
  922.          (setf (aref array y (index+ x 6))
  923.                (read-image-load-byte 1 6 byte))
  924.          (setf (aref array y (index+ x 7))
  925.                (read-image-load-byte 1 7 byte))))
  926.          )))))
  927.  
  928. (defun read-pixarray-4 (buffer-bbuf index array x y width height 
  929.             padded-bytes-per-line bits-per-pixel)
  930.   (declare (type buffer-bytes buffer-bbuf)
  931.        (type pixarray-4 array)
  932.        (type card16 x y width height)
  933.        (type array-index index padded-bytes-per-line)
  934.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  935.        (ignore bits-per-pixel))
  936.   #.(declare-buffun)
  937.   (with-vector (buffer-bbuf buffer-bytes)
  938.     (do* ((start (index+ index
  939.              (index* y padded-bytes-per-line)
  940.              (index-ceiling x 2))
  941.          (index+ start padded-bytes-per-line))
  942.       (y 0 (index1+ y))
  943.       (left-nibbles (index-mod (index- x) 2))
  944.       (right-nibbles (index-mod (index- width left-nibbles) 2))
  945.       (middle-nibbles (index- width left-nibbles right-nibbles))
  946.       (middle-bytes (index-floor middle-nibbles 2)))
  947.      ((index>= y height))
  948.       (declare (type array-index start y
  949.              left-nibbles right-nibbles middle-nibbles middle-bytes))
  950.       (unless (index-zerop left-nibbles)
  951.     (setf (aref array y 0)
  952.           (read-image-load-byte
  953.         4 4 (aref buffer-bbuf (index1- start)))))
  954.       (do* ((end (index+ start middle-bytes))
  955.         (i start (index1+ i))
  956.         (x left-nibbles (index+ x 2)))
  957.        ((index>= i end)
  958.         (unless (index-zerop right-nibbles)
  959.           (setf (aref array y (index+ left-nibbles middle-nibbles))
  960.             (read-image-load-byte 4 0 (aref buffer-bbuf end)))))
  961.     (declare (type array-index end i x))
  962.     (let ((byte (aref buffer-bbuf i)))
  963.       (declare (type card8 byte))
  964.       (setf (aref array y (index+ x 0))
  965.         (read-image-load-byte 4 0 byte))
  966.       (setf (aref array y (index+ x 1))
  967.         (read-image-load-byte 4 4 byte))))
  968.       )))
  969.  
  970. (defun read-pixarray-8 (buffer-bbuf index array x y width height 
  971.             padded-bytes-per-line bits-per-pixel)
  972.   (declare (type buffer-bytes buffer-bbuf)
  973.        (type pixarray-8 array)
  974.        (type card16 x y width height)
  975.        (type array-index index padded-bytes-per-line)
  976.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  977.        (ignore bits-per-pixel))
  978.   #.(declare-buffun)
  979.   (with-vector (buffer-bbuf buffer-bytes)
  980.     (do* ((start (index+ index
  981.              (index* y padded-bytes-per-line)
  982.              x)
  983.          (index+ start padded-bytes-per-line))
  984.       (y 0 (index1+ y)))
  985.      ((index>= y height))
  986.       (declare (type array-index start y))
  987.       (do* ((end (index+ start width))
  988.         (i start (index1+ i))
  989.         (x 0 (index1+ x)))
  990.        ((index>= i end))
  991.     (declare (type array-index end i x))
  992.     (setf (aref array y x)
  993.           (the card8 (aref buffer-bbuf i)))))))
  994.  
  995. (defun read-pixarray-16 (buffer-bbuf index array x y width height 
  996.              padded-bytes-per-line bits-per-pixel)
  997.   (declare (type buffer-bytes buffer-bbuf)
  998.        (type pixarray-16 array)
  999.        (type card16 width height)
  1000.        (type array-index index padded-bytes-per-line)
  1001.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1002.        (ignore bits-per-pixel))
  1003.   #.(declare-buffun)
  1004.   (with-vector (buffer-bbuf buffer-bytes)
  1005.     (do* ((start (index+ index
  1006.              (index* y padded-bytes-per-line)
  1007.              (index* x 2))
  1008.          (index+ start padded-bytes-per-line))
  1009.       (y 0 (index1+ y)))
  1010.      ((index>= y height))
  1011.       (declare (type array-index start y))
  1012.       (do* ((end (index+ start (index* width 2)))
  1013.         (i start (index+ i 2))
  1014.         (x 0 (index1+ x)))
  1015.        ((index>= i end))
  1016.     (declare (type array-index end i x))
  1017.     (setf (aref array y x)
  1018.           (read-image-assemble-bytes
  1019.         (aref buffer-bbuf (index+ i 0))
  1020.         (aref buffer-bbuf (index+ i 1))))))))
  1021.  
  1022. (defun read-pixarray-24 (buffer-bbuf index array x y width height 
  1023.              padded-bytes-per-line bits-per-pixel)
  1024.   (declare (type buffer-bytes buffer-bbuf)
  1025.        (type pixarray-24 array)
  1026.        (type card16 width height)
  1027.        (type array-index index padded-bytes-per-line)
  1028.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1029.        (ignore bits-per-pixel))
  1030.   #.(declare-buffun)
  1031.   (with-vector (buffer-bbuf buffer-bytes)
  1032.     (do* ((start (index+ index
  1033.              (index* y padded-bytes-per-line)
  1034.              (index* x 3))
  1035.          (index+ start padded-bytes-per-line))
  1036.       (y 0 (index1+ y)))
  1037.      ((index>= y height))
  1038.       (declare (type array-index start y))
  1039.       (do* ((end (index+ start (index* width 3)))
  1040.         (i start (index+ i 3))
  1041.         (x 0 (index1+ x)))
  1042.        ((index>= i end))
  1043.     (declare (type array-index end i x))
  1044.     (setf (aref array y x)
  1045.           (read-image-assemble-bytes
  1046.         (aref buffer-bbuf (index+ i 0))
  1047.         (aref buffer-bbuf (index+ i 1))
  1048.         (aref buffer-bbuf (index+ i 2))))))))
  1049.  
  1050. (defun read-pixarray-32 (buffer-bbuf index array x y width height 
  1051.              padded-bytes-per-line bits-per-pixel)
  1052.   (declare (type buffer-bytes buffer-bbuf)
  1053.        (type pixarray-32 array)
  1054.        (type card16 width height)
  1055.        (type array-index index padded-bytes-per-line)
  1056.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1057.        (ignore bits-per-pixel))
  1058.   #.(declare-buffun)
  1059.   (with-vector (buffer-bbuf buffer-bytes)
  1060.     (do* ((start (index+ index
  1061.              (index* y padded-bytes-per-line)
  1062.              (index* x 4))
  1063.          (index+ start padded-bytes-per-line))
  1064.       (y 0 (index1+ y)))
  1065.      ((index>= y height))
  1066.       (declare (type array-index start y))
  1067.       (do* ((end (index+ start (index* width 4)))
  1068.         (i start (index+ i 4))
  1069.         (x 0 (index1+ x)))
  1070.        ((index>= i end))
  1071.     (declare (type array-index end i x))
  1072.     (setf (aref array y x)
  1073.           (read-image-assemble-bytes
  1074.         (aref buffer-bbuf (index+ i 0))
  1075.         (aref buffer-bbuf (index+ i 1))
  1076.         (aref buffer-bbuf (index+ i 2))
  1077.         (aref buffer-bbuf (index+ i 3))))))))
  1078.  
  1079. (defun read-pixarray-internal
  1080.        (bbuf boffset pixarray x y width height padded-bytes-per-line
  1081.     bits-per-pixel read-pixarray-function
  1082.     from-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1083.     to-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1084.   (declare (type buffer-bytes bbuf)
  1085.        (type array-index boffset padded-bytes-per-line)
  1086.        (type pixarray pixarray)
  1087.        (type card16 x y width height)
  1088.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1089.        (type function read-pixarray-function)
  1090.        (type (member 8 16 32) from-unit to-unit)
  1091.        (type boolean from-byte-lsb-first-p from-bit-lsb-first-p
  1092.          to-byte-lsb-first-p to-bit-lsb-first-p))
  1093.   (multiple-value-bind (image-swap-function image-swap-lsb-first-p)
  1094.       (image-swap-function
  1095.     bits-per-pixel
  1096.     from-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1097.     to-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1098.     (if (eq image-swap-function 'image-noswap)
  1099.     (funcall
  1100.       read-pixarray-function
  1101.       bbuf boffset pixarray x y width height padded-bytes-per-line
  1102.       bits-per-pixel)
  1103.       (with-image-data-buffer (buf (index* height padded-bytes-per-line))
  1104.     (funcall
  1105.       (symbol-function image-swap-function) bbuf buf
  1106.       (index+ boffset (index* y padded-bytes-per-line)) 0
  1107.       (index-ceiling (index* (index+ x width) bits-per-pixel) 8)
  1108.       padded-bytes-per-line padded-bytes-per-line height
  1109.       image-swap-lsb-first-p)
  1110.     (funcall
  1111.       read-pixarray-function 
  1112.       buf 0 pixarray x 0 width height padded-bytes-per-line
  1113.       bits-per-pixel)))))
  1114.  
  1115. (defun read-pixarray
  1116.        (bbuf boffset pixarray x y width height padded-bytes-per-line
  1117.     bits-per-pixel unit byte-lsb-first-p bit-lsb-first-p)
  1118.   (declare (type buffer-bytes bbuf)
  1119.        (type array-index boffset padded-bytes-per-line)
  1120.        (type pixarray pixarray)
  1121.        (type card16 x y width height)
  1122.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1123.        (type (member 8 16 32) unit)
  1124.        (type boolean byte-lsb-first-p bit-lsb-first-p))
  1125.   (unless (fast-read-pixarray
  1126.         bbuf boffset pixarray x y width height padded-bytes-per-line
  1127.         bits-per-pixel unit byte-lsb-first-p bit-lsb-first-p)
  1128.     (read-pixarray-internal
  1129.       bbuf boffset pixarray x y width height padded-bytes-per-line
  1130.       bits-per-pixel 
  1131.       (ecase bits-per-pixel
  1132.     ( 1 #'read-pixarray-1 )
  1133.     ( 4 #'read-pixarray-4 )
  1134.     ( 8 #'read-pixarray-8 )
  1135.     (16 #'read-pixarray-16)
  1136.     (24 #'read-pixarray-24)
  1137.     (32 #'read-pixarray-32))
  1138.       unit byte-lsb-first-p bit-lsb-first-p
  1139.       *image-unit* *image-byte-lsb-first-p* *image-bit-lsb-first-p*)))
  1140.  
  1141. (defun read-xy-format-image-x
  1142.        (buffer-bbuf index length data width height depth
  1143.     padded-bytes-per-line padded-bytes-per-plane
  1144.     unit byte-lsb-first-p bit-lsb-first-p pad)
  1145.   (declare (type buffer-bytes buffer-bbuf)
  1146.        (type card16 width height)
  1147.        (type array-index index length padded-bytes-per-line
  1148.          padded-bytes-per-plane)
  1149.        (type image-depth depth)
  1150.        (type (member 8 16 32) unit pad)
  1151.        (type boolean byte-lsb-first-p bit-lsb-first-p)
  1152.        (values image-x))
  1153.   (assert (index<= (index* depth padded-bytes-per-plane) length))
  1154.   (let* ((bytes-per-line (index-ceiling width 8))
  1155.      (data-length (index* padded-bytes-per-plane depth)))
  1156.     (declare (type array-index bytes-per-line data-length))
  1157.     (cond (data
  1158.        (check-type data buffer-bytes)
  1159.        (assert (index>= (length data) data-length)))
  1160.       (t
  1161.        (setq data (make-array data-length :element-type 'card8))))
  1162.     (do ((plane 0 (index1+ plane)))
  1163.     ((index>= plane depth))
  1164.       (declare (type image-depth plane))
  1165.       (image-noswap
  1166.     buffer-bbuf data
  1167.     (index+ index (index* plane padded-bytes-per-plane))
  1168.     (index* plane padded-bytes-per-plane)
  1169.     bytes-per-line padded-bytes-per-line padded-bytes-per-line
  1170.     height byte-lsb-first-p))
  1171.     (create-image 
  1172.       :width width :height height :depth depth :data data
  1173.       :bits-per-pixel 1 :format :xy-pixmap
  1174.       :bytes-per-line padded-bytes-per-line
  1175.       :unit unit :pad pad
  1176.       :byte-lsb-first-p byte-lsb-first-p :bit-lsb-first-p bit-lsb-first-p)))
  1177.  
  1178. (defun read-z-format-image-x
  1179.        (buffer-bbuf index length data width height depth
  1180.     padded-bytes-per-line 
  1181.     unit byte-lsb-first-p bit-lsb-first-p pad bits-per-pixel)
  1182.   (declare (type buffer-bytes buffer-bbuf)
  1183.        (type card16 width height)
  1184.        (type array-index index length padded-bytes-per-line)
  1185.        (type image-depth depth)
  1186.        (type (member 8 16 32) unit pad)
  1187.        (type boolean byte-lsb-first-p bit-lsb-first-p)
  1188.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1189.        (values image-x))
  1190.   (assert (index<= (index* height padded-bytes-per-line) length))
  1191.   (let ((bytes-per-line (index-ceiling (index* width bits-per-pixel) 8))
  1192.     (data-length (index* padded-bytes-per-line height)))
  1193.     (declare (type array-index bytes-per-line data-length))
  1194.     (cond (data
  1195.        (check-type data buffer-bytes)
  1196.        (assert (index>= (length data) data-length)))
  1197.       (t
  1198.        (setq data (make-array data-length :element-type 'card8))))
  1199.     (image-noswap
  1200.       buffer-bbuf data index 0 bytes-per-line padded-bytes-per-line
  1201.       padded-bytes-per-line height byte-lsb-first-p)
  1202.     (create-image 
  1203.       :width width :height height :depth depth :data data
  1204.       :bits-per-pixel bits-per-pixel :format :z-pixmap
  1205.       :bytes-per-line padded-bytes-per-line
  1206.       :unit unit :pad pad
  1207.       :byte-lsb-first-p byte-lsb-first-p :bit-lsb-first-p bit-lsb-first-p)))
  1208.  
  1209. (defun read-image-xy (bbuf index length data x y width height depth
  1210.               padded-bytes-per-line padded-bytes-per-plane
  1211.               unit byte-lsb-first-p bit-lsb-first-p)
  1212.   (declare (type buffer-bytes bbuf)
  1213.        (type card16 x y width height)
  1214.        (type array-index index length padded-bytes-per-line
  1215.          padded-bytes-per-plane)
  1216.        (type image-depth depth)
  1217.        (type (member 8 16 32) unit)
  1218.        (type boolean byte-lsb-first-p bit-lsb-first-p)
  1219.        (values image-xy))
  1220.   (check-type data list)
  1221.   (multiple-value-bind (dimensions element-type)
  1222.       (if data
  1223.       (values (array-dimensions (first data))
  1224.           (array-element-type (first data)))
  1225.     (values (list height
  1226.               (index* (index-ceiling width *image-pad*) *image-pad*))
  1227.         'pixarray-1-element-type))
  1228.     (do* ((arrays data)
  1229.       (result nil)
  1230.       (limit (index+ length index))
  1231.       (plane 0 (1+ plane))
  1232.       (index index (index+ index padded-bytes-per-plane)))
  1233.      ((or (>= plane depth)
  1234.           (index> (index+ index padded-bytes-per-plane) limit))
  1235.       (setq data (nreverse result) depth (length data)))
  1236.       (declare (type array-index limit index)
  1237.            (type image-depth plane)
  1238.            (type list arrays result))
  1239.       (let ((array (or (pop arrays)
  1240.                (make-array dimensions :element-type element-type))))
  1241.     (declare (type pixarray-1 array))
  1242.     (push array result)
  1243.     (read-pixarray
  1244.       bbuf index array x y width height padded-bytes-per-line 1
  1245.       unit byte-lsb-first-p bit-lsb-first-p)))
  1246.     (create-image 
  1247.       :width width :height height :depth depth :data data)))
  1248.  
  1249. (defun read-image-z (bbuf index length data x y width height depth
  1250.              padded-bytes-per-line bits-per-pixel
  1251.              unit byte-lsb-first-p bit-lsb-first-p)
  1252.   (declare (type buffer-bytes bbuf)
  1253.        (type card16 x y width height)
  1254.        (type array-index index length padded-bytes-per-line)
  1255.        (type image-depth depth)
  1256.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1257.        (type (member 8 16 32) unit)
  1258.        (type boolean byte-lsb-first-p bit-lsb-first-p)
  1259.        (values image-z))
  1260.   (assert (index<= (index* (index+ y height) padded-bytes-per-line) length))
  1261.   (let* ((image-bits-per-line (index* width bits-per-pixel))
  1262.      (image-pixels-per-line
  1263.        (index-ceiling
  1264.          (index* (index-ceiling image-bits-per-line *image-pad*)
  1265.              *image-pad*)
  1266.          bits-per-pixel)))
  1267.     (declare (type array-index image-bits-per-line image-pixels-per-line))
  1268.     (unless data
  1269.       (setq data
  1270.         (make-array
  1271.           (list height image-pixels-per-line)
  1272.           :element-type (ecase bits-per-pixel
  1273.                   (1  'pixarray-1-element-type)
  1274.                   (4  'pixarray-4-element-type)
  1275.                   (8  'pixarray-8-element-type)
  1276.                   (16 'pixarray-16-element-type)
  1277.                   (24 'pixarray-24-element-type)
  1278.                   (32 'pixarray-32-element-type)))))
  1279.     (read-pixarray
  1280.       bbuf index data x y width height padded-bytes-per-line bits-per-pixel
  1281.       unit byte-lsb-first-p bit-lsb-first-p)
  1282.     (create-image 
  1283.       :width width :height height :depth depth :data data
  1284.       :bits-per-pixel bits-per-pixel)))
  1285.  
  1286. (defun get-image (drawable &key
  1287.           data
  1288.           (x (required-arg x))
  1289.           (y (required-arg y))
  1290.           (width (required-arg width))
  1291.           (height (required-arg height))
  1292.           plane-mask format result-type)
  1293.   (declare (type drawable drawable)
  1294.        (type (or buffer-bytes list pixarray) data)
  1295.        (type int16 x y) ;; required
  1296.        (type card16 width height) ;; required
  1297.        (type (or null pixel) plane-mask)
  1298.        (type (or null (member :xy-pixmap :z-pixmap)) format)
  1299.        (type (or null (member image-xy image-x image-z)) result-type)
  1300.        (values image visual-info))
  1301.   (unless result-type
  1302.     (setq result-type (ecase format
  1303.             (:xy-pixmap 'image-xy)
  1304.             (:z-pixmap 'image-z)
  1305.             ((nil) 'image-x))))
  1306.   (unless format
  1307.     (setq format (case result-type
  1308.            (image-xy :xy-pixmap)
  1309.            ((image-z image-x) :z-pixmap))))
  1310.   (unless (ecase result-type
  1311.         (image-xy (eq format :xy-pixmap))
  1312.         (image-z (eq format :z-pixmap))
  1313.         (image-x t))
  1314.     (error "Result-type ~s is incompatable with format ~s"
  1315.        result-type format))
  1316.   (unless plane-mask (setq plane-mask #xffffffff))
  1317.   (let ((display (drawable-display drawable)))
  1318.     (with-buffer-request-and-reply (display *x-getimage* nil :sizes (8 32))
  1319.      (((data (member error :xy-pixmap :z-pixmap)) format)
  1320.       (drawable drawable)
  1321.       (int16 x y)
  1322.       (card16 width height)
  1323.       (card32 plane-mask))
  1324.       (let* ((depth (card8-get 1))
  1325.          (length (index* 4 (card32-get 4)))
  1326.          (visual-info (visual-info display (resource-id-get 8)))
  1327.          (bitmap-format (display-bitmap-format display))
  1328.          (unit (bitmap-format-unit bitmap-format))
  1329.          (byte-lsb-first-p (display-image-lsb-first-p display))
  1330.          (bit-lsb-first-p  (bitmap-format-lsb-first-p bitmap-format)))
  1331.     (declare (type image-depth depth)
  1332.          (type array-index length)
  1333.          (type (or null visual-info) visual-info)
  1334.          (type bitmap-format bitmap-format)
  1335.          (type (member 8 16 32) unit)
  1336.          (type boolean byte-lsb-first-p bit-lsb-first-p))
  1337.     (multiple-value-bind (pad bits-per-pixel)
  1338.         (ecase format
  1339.           (:xy-pixmap
  1340.         (values (bitmap-format-pad bitmap-format) 1))
  1341.           (:z-pixmap
  1342.         (if (= depth 1)
  1343.             (values (bitmap-format-pad bitmap-format) 1)
  1344.           (let ((pixmap-format
  1345.               (find depth (display-pixmap-formats display)
  1346.                 :key #'pixmap-format-depth)))
  1347.             (declare (type pixmap-format pixmap-format))
  1348.             (values (pixmap-format-scanline-pad pixmap-format)
  1349.                 (pixmap-format-bits-per-pixel pixmap-format))))))
  1350.       (declare (type (member 8 16 32) pad)
  1351.            (type (member 1 4 8 16 24 32) bits-per-pixel))
  1352.       (let* ((bits-per-line (index* bits-per-pixel width))
  1353.          (padded-bits-per-line
  1354.            (index* (index-ceiling bits-per-line pad) pad))
  1355.          (padded-bytes-per-line
  1356.            (index-ceiling padded-bits-per-line 8))
  1357.          (padded-bytes-per-plane
  1358.            (index* padded-bytes-per-line height))
  1359.          (image
  1360.            (ecase result-type
  1361.              (image-x
  1362.                (ecase format
  1363.              (:xy-pixmap
  1364.                (read-xy-format-image-x
  1365.                  buffer-bbuf *replysize* length data
  1366.                  width height depth
  1367.                  padded-bytes-per-line padded-bytes-per-plane
  1368.                  unit byte-lsb-first-p bit-lsb-first-p
  1369.                  pad))
  1370.              (:z-pixmap
  1371.                (read-z-format-image-x
  1372.                  buffer-bbuf *replysize* length data
  1373.                  width height depth
  1374.                  padded-bytes-per-line
  1375.                  unit byte-lsb-first-p bit-lsb-first-p
  1376.                  pad bits-per-pixel))))
  1377.              (image-xy
  1378.                (read-image-xy
  1379.              buffer-bbuf *replysize* length data
  1380.              0 0 width height depth
  1381.              padded-bytes-per-line padded-bytes-per-plane
  1382.              unit byte-lsb-first-p bit-lsb-first-p))
  1383.              (image-z
  1384.                (read-image-z
  1385.              buffer-bbuf *replysize* length data
  1386.              0 0 width height depth padded-bytes-per-line
  1387.              bits-per-pixel 
  1388.              unit byte-lsb-first-p bit-lsb-first-p)))))
  1389.         (declare (type image image)
  1390.              (type array-index bits-per-line 
  1391.                padded-bits-per-line padded-bytes-per-line))
  1392.         (when visual-info
  1393.           (unless (zerop (visual-info-red-mask visual-info))
  1394.         (setf (image-red-mask image)
  1395.               (visual-info-red-mask visual-info)))
  1396.           (unless (zerop (visual-info-green-mask visual-info))
  1397.         (setf (image-green-mask image)
  1398.               (visual-info-green-mask visual-info)))
  1399.           (unless (zerop (visual-info-blue-mask visual-info))
  1400.         (setf (image-blue-mask image)
  1401.               (visual-info-blue-mask visual-info))))
  1402.         (values image visual-info)))))))
  1403.  
  1404.  
  1405. ;;;-----------------------------------------------------------------------------
  1406. ;;; PUT-IMAGE
  1407.  
  1408. (defun write-pixarray-1 (buffer-bbuf index array x y width height
  1409.              padded-bytes-per-line bits-per-pixel)
  1410.   (declare (type buffer-bytes buffer-bbuf)
  1411.        (type pixarray-1 array)
  1412.        (type card16 x y width height)
  1413.        (type array-index index padded-bytes-per-line)
  1414.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1415.        (ignore bits-per-pixel))
  1416.   #.(declare-buffun)
  1417.   (with-vector (buffer-bbuf buffer-bytes)
  1418.     (do* ((h 0 (index1+ h))
  1419.       (y y (index1+ y))
  1420.       (right-bits (index-mod width 8))
  1421.       (middle-bits (index- width right-bits))
  1422.       (middle-bytes (index-ceiling middle-bits 8))
  1423.       (start index (index+ start padded-bytes-per-line)))
  1424.      ((index>= h height))
  1425.       (declare (type array-index h y right-bits middle-bits
  1426.              middle-bytes start))
  1427.       (do* ((end (index+ start middle-bytes))
  1428.         (i start (index1+ i))
  1429.         (start-x x)
  1430.         (x start-x (index+ x 8)))
  1431.        ((index>= i end)
  1432.         (unless (index-zerop right-bits)
  1433.           (let ((x (index+ start-x middle-bits)))
  1434.         (declare (type array-index x))
  1435.         (setf (aref buffer-bbuf end)
  1436.               (write-image-assemble-bytes
  1437.             (aref array y (index+ x 0))
  1438.             (if (index> right-bits 1)
  1439.                 (aref array y (index+ x 1))
  1440.               0)
  1441.             (if (index> right-bits 2)
  1442.                 (aref array y (index+ x 2))
  1443.               0)
  1444.             (if (index> right-bits 3)
  1445.                 (aref array y (index+ x 3))
  1446.               0)
  1447.             (if (index> right-bits 4)
  1448.                 (aref array y (index+ x 4))
  1449.               0)
  1450.             (if (index> right-bits 5)
  1451.                 (aref array y (index+ x 5))
  1452.               0)
  1453.             (if (index> right-bits 6)
  1454.                 (aref array y (index+ x 6))
  1455.               0)
  1456.             0)))))
  1457.     (declare (type array-index end i start-x x))
  1458.     (setf (aref buffer-bbuf i)
  1459.           (write-image-assemble-bytes
  1460.         (aref array y (index+ x 0))
  1461.         (aref array y (index+ x 1))
  1462.         (aref array y (index+ x 2))
  1463.         (aref array y (index+ x 3))
  1464.         (aref array y (index+ x 4))
  1465.         (aref array y (index+ x 5))
  1466.         (aref array y (index+ x 6))
  1467.         (aref array y (index+ x 7))))))))
  1468.  
  1469. (defun write-pixarray-4 (buffer-bbuf index array x y width height
  1470.              padded-bytes-per-line bits-per-pixel)
  1471.   (declare (type buffer-bytes buffer-bbuf)
  1472.        (type pixarray-4 array)
  1473.        (type int16 x y)
  1474.        (type card16 width height)
  1475.        (type array-index index padded-bytes-per-line)
  1476.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1477.        (ignore bits-per-pixel))
  1478.   #.(declare-buffun)
  1479.   (with-vector (buffer-bbuf buffer-bytes)
  1480.     (do* ((h 0 (index1+ h))
  1481.       (y y (index1+ y))
  1482.       (right-nibbles (index-mod width 2))
  1483.       (middle-nibbles (index- width right-nibbles))
  1484.       (middle-bytes (index-ceiling middle-nibbles 2))
  1485.       (start index (index+ start padded-bytes-per-line)))
  1486.      ((index>= h height))
  1487.       (declare (type array-index h y right-nibbles middle-nibbles
  1488.              middle-bytes start))
  1489.       (do* ((end (index+ start middle-bytes))
  1490.         (i start (index1+ i))
  1491.         (start-x x)
  1492.         (x start-x (index+ x 2)))
  1493.        ((index>= i end)
  1494.         (unless (index-zerop right-nibbles)
  1495.           (setf (aref buffer-bbuf end)
  1496.             (write-image-assemble-bytes
  1497.               (aref array y (index+ start-x middle-nibbles))
  1498.               0))))
  1499.     (declare (type array-index end i start-x x))
  1500.     (setf (aref buffer-bbuf i)
  1501.           (write-image-assemble-bytes
  1502.         (aref array y (index+ x 0))
  1503.         (aref array y (index+ x 1))))))))
  1504.  
  1505. (defun write-pixarray-8 (buffer-bbuf index array x y width height
  1506.              padded-bytes-per-line bits-per-pixel)
  1507.   (declare (type buffer-bytes buffer-bbuf)
  1508.        (type pixarray-8 array)
  1509.        (type int16 x y)
  1510.        (type card16 width height)
  1511.        (type array-index index padded-bytes-per-line)
  1512.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1513.        (ignore bits-per-pixel))
  1514.   #.(declare-buffun)
  1515.   (with-vector (buffer-bbuf buffer-bytes)
  1516.     (do* ((h 0 (index1+ h))
  1517.       (y y (index1+ y))
  1518.       (start index (index+ start padded-bytes-per-line)))
  1519.      ((index>= h height))
  1520.       (declare (type array-index h y start))
  1521.       (do* ((end (index+ start width))
  1522.         (i start (index1+ i))
  1523.         (x x (index1+ x)))
  1524.        ((index>= i end))
  1525.     (declare (type array-index end i x))
  1526.     (setf (aref buffer-bbuf i) (the card8 (aref array y x)))))))
  1527.  
  1528. (defun write-pixarray-16 (buffer-bbuf index array x y width height
  1529.               padded-bytes-per-line bits-per-pixel)
  1530.   (declare (type buffer-bytes buffer-bbuf)
  1531.        (type pixarray-16 array)
  1532.        (type int16 x y)
  1533.        (type card16 width height)
  1534.        (type array-index index padded-bytes-per-line)
  1535.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1536.        (ignore bits-per-pixel))
  1537.   #.(declare-buffun)
  1538.   (with-vector (buffer-bbuf buffer-bytes)
  1539.     (do* ((h 0 (index1+ h))
  1540.       (y y (index1+ y))
  1541.       (start index (index+ start padded-bytes-per-line)))
  1542.      ((index>= h height))
  1543.       (declare (type array-index h y start))
  1544.       (do* ((end (index+ start (index* width 2)))
  1545.         (i start (index+ i 2))
  1546.         (x x (index1+ x)))
  1547.        ((index>= i end))
  1548.     (declare (type array-index end i x))
  1549.     (let ((pixel (aref array y x)))
  1550.       (declare (type pixarray-16-element-type pixel))
  1551.       (setf (aref buffer-bbuf (index+ i 0))
  1552.         (write-image-load-byte 0 pixel 16))
  1553.       (setf (aref buffer-bbuf (index+ i 1))
  1554.         (write-image-load-byte 8 pixel 16)))))))
  1555.  
  1556. (defun write-pixarray-24 (buffer-bbuf index array x y width height
  1557.               padded-bytes-per-line bits-per-pixel)
  1558.   (declare (type buffer-bytes buffer-bbuf)
  1559.        (type pixarray-24 array)
  1560.        (type int16 x y)
  1561.        (type card16 width height)
  1562.        (type array-index index padded-bytes-per-line)
  1563.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1564.        (ignore bits-per-pixel))
  1565.   #.(declare-buffun)
  1566.   (with-vector (buffer-bbuf buffer-bytes)
  1567.     (do* ((h 0 (index1+ h))
  1568.       (y y (index1+ y))
  1569.       (start index (index+ start padded-bytes-per-line)))
  1570.      ((index>= h height))
  1571.       (declare (type array-index y start))
  1572.       (do* ((end (index+ start (index* width 3)))
  1573.         (i start (index+ i 3))
  1574.         (x x (index1+ x)))
  1575.        ((index>= i end))
  1576.     (declare (type array-index end i x))
  1577.     (let ((pixel (aref array y x)))
  1578.       (declare (type pixarray-24-element-type pixel))
  1579.       (setf (aref buffer-bbuf (index+ i 0))
  1580.         (write-image-load-byte 0 pixel 24))
  1581.       (setf (aref buffer-bbuf (index+ i 1))
  1582.         (write-image-load-byte 8 pixel 24))
  1583.       (setf (aref buffer-bbuf (index+ i 2))
  1584.         (write-image-load-byte 16 pixel 24)))))))
  1585.  
  1586. (defun write-pixarray-32 (buffer-bbuf index array x y width height
  1587.               padded-bytes-per-line bits-per-pixel)
  1588.   (declare (type buffer-bytes buffer-bbuf)
  1589.        (type pixarray-32 array)
  1590.        (type int16 x y)
  1591.        (type card16 width height)
  1592.        (type array-index index padded-bytes-per-line)
  1593.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1594.        (ignore bits-per-pixel))
  1595.   #.(declare-buffun)
  1596.   (with-vector (buffer-bbuf buffer-bytes)
  1597.     (do* ((h 0 (index1+ h))
  1598.       (y y (index1+ y))
  1599.       (start index (index+ start padded-bytes-per-line)))
  1600.      ((index>= h height))
  1601.       (declare (type array-index h y start))
  1602.       (do* ((end (index+ start (index* width 4)))
  1603.         (i start (index+ i 4))
  1604.         (x x (index1+ x)))
  1605.        ((index>= i end))
  1606.     (declare (type array-index end i x))
  1607.     (let ((pixel (aref array y x)))
  1608.       (declare (type pixarray-32-element-type pixel))
  1609.       (setf (aref buffer-bbuf (index+ i 0))
  1610.         (write-image-load-byte 0 pixel 32))
  1611.       (setf (aref buffer-bbuf (index+ i 1))
  1612.         (write-image-load-byte 8 pixel 32))
  1613.       (setf (aref buffer-bbuf (index+ i 2))
  1614.         (write-image-load-byte 16 pixel 32))
  1615.       (setf (aref buffer-bbuf (index+ i 2))
  1616.         (write-image-load-byte 24 pixel 32)))))))
  1617.  
  1618. (defun write-pixarray-internal
  1619.        (bbuf boffset pixarray x y width height padded-bytes-per-line
  1620.     bits-per-pixel write-pixarray-function
  1621.     from-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1622.     to-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1623.   (declare (type buffer-bytes bbuf)
  1624.        (type pixarray pixarray)
  1625.        (type card16 x y width height)
  1626.        (type array-index boffset padded-bytes-per-line)
  1627.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1628.        (type function write-pixarray-function)
  1629.        (type (member 8 16 32) from-unit to-unit)
  1630.        (type boolean from-byte-lsb-first-p from-bit-lsb-first-p
  1631.          to-byte-lsb-first-p to-bit-lsb-first-p))
  1632.   (multiple-value-bind (image-swap-function image-swap-lsb-first-p)
  1633.       (image-swap-function
  1634.     bits-per-pixel
  1635.     from-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1636.     to-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1637.     (declare (type symbol image-swap-function)
  1638.          (type boolean image-swap-lsb-first-p))
  1639.     (if (eq image-swap-function 'image-noswap)
  1640.     (funcall
  1641.       write-pixarray-function
  1642.       bbuf boffset pixarray x y width height padded-bytes-per-line
  1643.       bits-per-pixel)
  1644.       (with-image-data-buffer (buf (index* height padded-bytes-per-line))
  1645.     (funcall
  1646.       write-pixarray-function 
  1647.       buf 0 pixarray x y width height padded-bytes-per-line
  1648.       bits-per-pixel)
  1649.     (funcall
  1650.       (symbol-function image-swap-function) buf bbuf 0 boffset
  1651.       (index-ceiling (index* width bits-per-pixel) 8)
  1652.       padded-bytes-per-line padded-bytes-per-line height
  1653.       image-swap-lsb-first-p)))))
  1654.  
  1655. (defun write-pixarray
  1656.        (bbuf boffset pixarray x y width height padded-bytes-per-line
  1657.     bits-per-pixel unit byte-lsb-first-p bit-lsb-first-p)
  1658.   (declare (type buffer-bytes bbuf)
  1659.        (type pixarray pixarray)
  1660.        (type card16 x y width height)
  1661.        (type array-index boffset padded-bytes-per-line)
  1662.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1663.        (type (member 8 16 32) unit)
  1664.        (type boolean byte-lsb-first-p bit-lsb-first-p))
  1665.   (unless (fast-write-pixarray
  1666.         bbuf boffset pixarray x y width height padded-bytes-per-line
  1667.         bits-per-pixel unit byte-lsb-first-p bit-lsb-first-p)
  1668.     (write-pixarray-internal
  1669.       bbuf boffset pixarray x y width height padded-bytes-per-line
  1670.       bits-per-pixel
  1671.       (ecase bits-per-pixel
  1672.     ( 1 #'write-pixarray-1 )
  1673.     ( 4 #'write-pixarray-4 )
  1674.     ( 8 #'write-pixarray-8 )
  1675.     (16 #'write-pixarray-16)
  1676.     (24 #'write-pixarray-24)
  1677.     (32 #'write-pixarray-32))
  1678.       *image-unit* *image-byte-lsb-first-p* *image-bit-lsb-first-p*
  1679.       unit byte-lsb-first-p bit-lsb-first-p)))
  1680.  
  1681. (defun write-xy-format-image-x-data
  1682.        (data obuf data-start obuf-start x y width height
  1683.     from-padded-bytes-per-line to-padded-bytes-per-line
  1684.     from-bitmap-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1685.     to-bitmap-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1686.   (declare (type buffer-bytes data obuf)
  1687.        (type array-index data-start obuf-start
  1688.          from-padded-bytes-per-line to-padded-bytes-per-line)
  1689.        (type card16 x y width height)
  1690.        (type (member 8 16 32) from-bitmap-unit to-bitmap-unit)
  1691.        (type boolean from-byte-lsb-first-p from-bit-lsb-first-p
  1692.          to-byte-lsb-first-p to-bit-lsb-first-p))
  1693.   (assert (index-zerop (index-mod x 8)))
  1694.   (multiple-value-bind (image-swap-function image-swap-lsb-first-p)
  1695.       (image-swap-function
  1696.     1
  1697.     from-bitmap-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1698.     to-bitmap-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1699.     (declare (type symbol image-swap-function)
  1700.          (type boolean image-swap-lsb-first-p))
  1701.     (let ((x-mod-unit (index-mod x from-bitmap-unit)))
  1702.       (declare (type card16 x-mod-unit))
  1703.       (if (and (index-plusp x-mod-unit)
  1704.            (not (eq from-byte-lsb-first-p from-bit-lsb-first-p)))
  1705.       (let* ((temp-width (index+ width x-mod-unit))
  1706.          (temp-bytes-per-line (index-ceiling temp-width 8))
  1707.          (temp-padded-bits-per-line
  1708.            (index* (index-ceiling temp-width from-bitmap-unit)
  1709.                from-bitmap-unit))
  1710.          (temp-padded-bytes-per-line
  1711.            (index-ceiling temp-padded-bits-per-line 8)))
  1712.         (declare (type card16 temp-width temp-bytes-per-line
  1713.                temp-padded-bits-per-line temp-padded-bytes-per-line))
  1714.         (with-image-data-buffer
  1715.          (buf (index* height temp-padded-bytes-per-line))
  1716.           (funcall
  1717.         (symbol-function image-swap-function) data buf
  1718.         (index+ data-start
  1719.             (index* y from-padded-bytes-per-line)
  1720.             (index-floor (index- x x-mod-unit) 8))
  1721.         0 temp-bytes-per-line from-padded-bytes-per-line
  1722.         temp-padded-bytes-per-line height image-swap-lsb-first-p)
  1723.           (write-xy-format-image-x-data
  1724.         buf obuf 0 obuf-start x-mod-unit 0 width height
  1725.         temp-padded-bytes-per-line to-padded-bytes-per-line
  1726.         from-bitmap-unit to-byte-lsb-first-p to-byte-lsb-first-p
  1727.         to-bitmap-unit to-byte-lsb-first-p to-bit-lsb-first-p)))
  1728.     (funcall
  1729.       (symbol-function image-swap-function) data obuf 
  1730.       (index+ data-start
  1731.           (index* y from-padded-bytes-per-line)
  1732.           (index-floor x 8))
  1733.       obuf-start (index-ceiling width 8) from-padded-bytes-per-line
  1734.       to-padded-bytes-per-line height image-swap-lsb-first-p)))))
  1735.  
  1736. (defun write-xy-format-image-x
  1737.        (display image src-x src-y width height
  1738.     padded-bytes-per-line
  1739.     unit byte-lsb-first-p bit-lsb-first-p)
  1740.   (declare (type display display)
  1741.        (type image-x image)
  1742.        (type int16 src-x src-y)
  1743.        (type card16 width height)
  1744.        (type array-index padded-bytes-per-line)
  1745.        (type (member 8 16 32) unit)
  1746.        (type boolean byte-lsb-first-p bit-lsb-first-p))
  1747.   (dotimes (plane (image-depth image))
  1748.     (let ((data-start
  1749.         (index* (index* plane (image-height image))
  1750.             (image-x-bytes-per-line image)))
  1751.       (src-y src-y)
  1752.       (height height))
  1753.       (declare (type int16 src-y)
  1754.            (type card16 height))
  1755.       (loop 
  1756.     (when (index-zerop height) (return))
  1757.     (let ((nlines
  1758.         (index-min (index-floor (index- (buffer-size display)
  1759.                         (buffer-boffset display))
  1760.                     padded-bytes-per-line)
  1761.                height)))
  1762.       (declare (type array-index nlines))
  1763.       (when (index-plusp nlines)
  1764.         (write-xy-format-image-x-data
  1765.           (image-x-data image) (buffer-obuf8 display)
  1766.           data-start (buffer-boffset display)
  1767.           src-x src-y width nlines 
  1768.           (image-x-bytes-per-line image) padded-bytes-per-line
  1769.           (image-x-unit image) (image-x-byte-lsb-first-p image)
  1770.           (image-x-bit-lsb-first-p image)
  1771.           unit byte-lsb-first-p bit-lsb-first-p)
  1772.         (index-incf (buffer-boffset display)
  1773.             (index* nlines padded-bytes-per-line))
  1774.         (index-incf src-y nlines)
  1775.         (when (index-zerop (index-decf height nlines)) (return))))
  1776.     (buffer-flush display)))))
  1777.  
  1778. (defun write-z-format-image-x-data
  1779.        (data obuf data-start obuf-start x y width height
  1780.     from-padded-bytes-per-line to-padded-bytes-per-line
  1781.     bits-per-pixel
  1782.     from-bitmap-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1783.     to-bitmap-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1784.   (declare (type buffer-bytes data obuf)
  1785.        (type array-index data-start obuf-start
  1786.          from-padded-bytes-per-line to-padded-bytes-per-line)
  1787.        (type card16 x y width height)
  1788.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1789.        (type (member 8 16 32) from-bitmap-unit to-bitmap-unit)
  1790.        (type boolean from-byte-lsb-first-p from-bit-lsb-first-p
  1791.          to-byte-lsb-first-p to-bit-lsb-first-p))
  1792.   (if (index= bits-per-pixel 1)
  1793.       (write-xy-format-image-x-data
  1794.     data obuf data-start obuf-start x y width height
  1795.     from-padded-bytes-per-line to-padded-bytes-per-line
  1796.     from-bitmap-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1797.     to-bitmap-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1798.     (let ((srcoff
  1799.         (index+ data-start
  1800.             (index* y from-padded-bytes-per-line)
  1801.             (index-floor (index* x bits-per-pixel) 8)))
  1802.       (srclen (index-ceiling (index* width bits-per-pixel) 8)))
  1803.       (declare (type array-index srcoff srclen))
  1804.       (if (and (index= bits-per-pixel 4) (index-oddp x))
  1805.       (with-image-data-buffer (buf (index* height to-padded-bytes-per-line))
  1806.         (image-swap-nibbles-left
  1807.           data buf srcoff 0 srclen
  1808.           from-padded-bytes-per-line to-padded-bytes-per-line height nil)
  1809.         (write-z-format-image-x-data
  1810.           buf obuf 0 obuf-start 0 0 width height
  1811.           to-padded-bytes-per-line to-padded-bytes-per-line
  1812.           bits-per-pixel
  1813.           from-bitmap-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1814.           to-bitmap-unit to-byte-lsb-first-p to-bit-lsb-first-p))
  1815.     (multiple-value-bind (image-swap-function image-swap-lsb-first-p)
  1816.         (image-swap-function
  1817.           bits-per-pixel
  1818.           from-bitmap-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1819.           to-bitmap-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1820.       (declare (type symbol image-swap-function)
  1821.            (type boolean image-swap-lsb-first-p))
  1822.       (funcall
  1823.         (symbol-function image-swap-function) data obuf srcoff obuf-start
  1824.         srclen from-padded-bytes-per-line to-padded-bytes-per-line height
  1825.         image-swap-lsb-first-p))))))
  1826.  
  1827. (defun write-z-format-image-x (display image src-x src-y width height
  1828.                    padded-bytes-per-line
  1829.                    unit byte-lsb-first-p bit-lsb-first-p)
  1830.   (declare (type display display)
  1831.        (type image-x image)
  1832.        (type int16 src-x src-y)
  1833.        (type card16 width height)
  1834.        (type array-index padded-bytes-per-line)
  1835.        (type boolean byte-lsb-first-p bit-lsb-first-p))
  1836.   (loop 
  1837.     (when (index-zerop height) (return))
  1838.     (let ((nlines
  1839.         (index-min (index-floor (index- (buffer-size display)
  1840.                         (buffer-boffset display))
  1841.                     padded-bytes-per-line)
  1842.                height)))
  1843.       (declare (type array-index nlines))
  1844.       (when (index-plusp nlines)
  1845.     (write-z-format-image-x-data 
  1846.       (image-x-data image) (buffer-obuf8 display) 0 (buffer-boffset display)
  1847.       src-x src-y width nlines
  1848.       (image-x-bytes-per-line image) padded-bytes-per-line
  1849.       (image-x-bits-per-pixel image)
  1850.       (image-x-unit image) (image-x-byte-lsb-first-p image)
  1851.       (image-x-bit-lsb-first-p image)
  1852.       unit byte-lsb-first-p bit-lsb-first-p)
  1853.     (index-incf (buffer-boffset display)
  1854.             (index* nlines padded-bytes-per-line))
  1855.     (index-incf src-y nlines)
  1856.     (when (index-zerop (index-decf height nlines)) (return))))
  1857.     (buffer-flush display)))
  1858.  
  1859. (defun write-image-xy (display image src-x src-y width height
  1860.                padded-bytes-per-line
  1861.                unit byte-lsb-first-p bit-lsb-first-p)
  1862.   (declare (type display display)
  1863.        (type image-xy image)
  1864.        (type array-index padded-bytes-per-line)
  1865.        (type int16 src-x src-y)
  1866.        (type card16 width height)
  1867.        (type (member 8 16 32) unit)
  1868.        (type boolean byte-lsb-first-p bit-lsb-first-p))
  1869.   (dolist (bitmap (image-xy-bitmap-list image))
  1870.     (declare (type pixarray-1 bitmap))
  1871.     (let ((src-y src-y)
  1872.       (height height))
  1873.       (declare (type int16 src-y)
  1874.            (type card16 height))
  1875.       (loop 
  1876.     (let ((nlines
  1877.         (index-min (index-floor (index- (buffer-size display)
  1878.                         (buffer-boffset display))
  1879.                     padded-bytes-per-line)
  1880.                height)))
  1881.       (declare (type array-index nlines))
  1882.       (when (index-plusp nlines)
  1883.         (write-pixarray 
  1884.           (buffer-obuf8 display) (buffer-boffset display)
  1885.           bitmap src-x src-y width nlines
  1886.           padded-bytes-per-line 1
  1887.           unit byte-lsb-first-p bit-lsb-first-p)
  1888.         (index-incf (buffer-boffset display)
  1889.             (index* nlines padded-bytes-per-line))
  1890.         (index-incf src-y nlines)
  1891.         (when (index-zerop (index-decf height nlines)) (return))))
  1892.     (buffer-flush display)))))
  1893.  
  1894. (defun write-image-z (display image src-x src-y width height
  1895.               padded-bytes-per-line
  1896.               unit byte-lsb-first-p bit-lsb-first-p)
  1897.   (declare (type display display)
  1898.        (type image-z image)
  1899.        (type array-index padded-bytes-per-line)
  1900.        (type int16 src-x src-y)
  1901.        (type card16 width height)
  1902.        (type (member 8 16 32) unit)
  1903.        (type boolean byte-lsb-first-p bit-lsb-first-p))
  1904.   (loop 
  1905.     (let ((bits-per-pixel (image-z-bits-per-pixel image))
  1906.       (nlines
  1907.         (index-min (index-floor (index- (buffer-size display)
  1908.                         (buffer-boffset display))
  1909.                     padded-bytes-per-line)
  1910.                height)))
  1911.       (declare (type (member 1 4 8 16 24 32) bits-per-pixel)
  1912.            (type array-index nlines))
  1913.       (when (index-plusp nlines)
  1914.     (write-pixarray
  1915.       (buffer-obuf8 display) (buffer-boffset display)
  1916.       (image-z-pixarray image) src-x src-y width nlines
  1917.       padded-bytes-per-line bits-per-pixel
  1918.       unit byte-lsb-first-p bit-lsb-first-p)
  1919.     (index-incf (buffer-boffset display)
  1920.             (index* nlines padded-bytes-per-line))
  1921.     (index-incf src-y nlines)
  1922.     (when (index-zerop (index-decf height nlines)) (return))))
  1923.     (buffer-flush display)))
  1924.  
  1925. ;;; Note:    The only difference between a format of :bitmap and :xy-pixmap
  1926. ;;;        of depth 1 is that when sending a :bitmap format the foreground 
  1927. ;;;        and background in the gcontext are used.
  1928.  
  1929. (defun put-image (drawable gcontext image &key
  1930.           (src-x 0) (src-y 0)        ;Position within image
  1931.           (x (required-arg x))        ;Position within drawable
  1932.           (y (required-arg y))
  1933.           width height
  1934.           bitmap-p)
  1935.   ;; Copy an image into a drawable.
  1936.   ;; WIDTH and HEIGHT default from IMAGE.
  1937.   ;; When BITMAP-P, force format to be :bitmap when depth=1.
  1938.   ;; This causes gcontext to supply foreground & background pixels.
  1939.   (declare (type drawable drawable)
  1940.        (type gcontext gcontext)
  1941.        (type image image)
  1942.        (type int16 x y) ;; required
  1943.        (type int16 src-x src-y)
  1944.        (type (or null card16) width height)
  1945.        (type boolean bitmap-p))
  1946.   (let* ((format
  1947.        (etypecase image
  1948.          (image-x (image-x-format (the image-x image)))
  1949.          (image-xy :xy-pixmap)
  1950.          (image-z :z-pixmap)))
  1951.      (src-x
  1952.        (if (image-x-p image)
  1953.            (index+ src-x (image-x-left-pad (the image-x image)))
  1954.          src-x))
  1955.      (image-width (image-width image))
  1956.      (image-height (image-height image))
  1957.      (width (min (or width image-width) (index- image-width src-x)))
  1958.      (height (min (or height image-height) (index- image-height src-y)))
  1959.      (depth (image-depth image))
  1960.      (display (drawable-display drawable))
  1961.      (bitmap-format (display-bitmap-format display))
  1962.      (unit (bitmap-format-unit bitmap-format))
  1963.      (byte-lsb-first-p (display-image-lsb-first-p display))
  1964.      (bit-lsb-first-p  (bitmap-format-lsb-first-p bitmap-format)))
  1965.     (declare (type (member :bitmap :xy-pixmap :z-pixmap) format)
  1966.          (type card16 src-x image-width image-height width height)
  1967.          (type image-depth depth)
  1968.          (type display display)
  1969.          (type bitmap-format bitmap-format)
  1970.          (type (member 8 16 32) unit)
  1971.          (type boolean byte-lsb-first-p bit-lsb-first-p))
  1972.     (when (and bitmap-p (not (index= depth 1)))
  1973.       (error "Bitmaps must have depth 1"))
  1974.     (unless (index<= 0 src-x (index1- (image-width image)))
  1975.       (error "src-x not inside image"))
  1976.     (unless (index<= 0 src-y (index1- (image-height image)))
  1977.       (error "src-y not inside image"))
  1978.     (when (and (index> width 0) (index> height 0))
  1979.       (multiple-value-bind (pad bits-per-pixel)
  1980.       (ecase format
  1981.         ((:bitmap :xy-pixmap)
  1982.           (values (bitmap-format-pad bitmap-format) 1))
  1983.         (:z-pixmap
  1984.           (if (= depth 1) 
  1985.           (values (bitmap-format-pad bitmap-format) 1)
  1986.         (let ((pixmap-format
  1987.             (find depth (display-pixmap-formats display)
  1988.                   :key #'pixmap-format-depth)))
  1989.           (declare (type (or null pixmap-format) pixmap-format))
  1990.           (if (null pixmap-format)
  1991.               (error "The depth of the image ~s does not match any server pixmap format." image))
  1992.           (if (not (= (typecase image
  1993.                 (image-z (image-z-bits-per-pixel image))
  1994.                 (image-x (image-x-bits-per-pixel image)))
  1995.                   (pixmap-format-bits-per-pixel pixmap-format)))
  1996.               ;; We could try to use the "/* XXX slow, but works */"
  1997.               ;; code in XPutImage from X11R4 here.  However, that
  1998.               ;; would require considerable support code
  1999.               ;; (see XImUtil.c, etc).
  2000.               (error "The bits-per-pixel of the image ~s does not match any server pixmap format." image))
  2001.           (values (pixmap-format-scanline-pad pixmap-format)
  2002.               (pixmap-format-bits-per-pixel pixmap-format))))))
  2003.     (declare (type (member 8 16 32) pad)
  2004.          (type (member 1 4 8 16 24 32) bits-per-pixel))
  2005.     (let* ((left-pad
  2006.          (if (or (eq format :xy-pixmap) (= depth 1))
  2007.              (index-mod src-x (index-min pad *image-pad*))
  2008.            0))
  2009.            (left-padded-src-x (index- src-x left-pad))
  2010.            (left-padded-width (index+ width left-pad))
  2011.            (bits-per-line (index* left-padded-width bits-per-pixel))
  2012.            (padded-bits-per-line
  2013.          (index* (index-ceiling bits-per-line pad) pad))
  2014.            (padded-bytes-per-line (index-ceiling padded-bits-per-line 8))
  2015.            (request-bytes-per-line
  2016.          (ecase format
  2017.            ((:bitmap :xy-pixmap) (index* padded-bytes-per-line depth))
  2018.            (:z-pixmap padded-bytes-per-line)))
  2019.            (max-bytes-per-request
  2020.          (index* (index- (display-max-request-length display) 6) 4))
  2021.            (max-request-height
  2022.          (floor max-bytes-per-request request-bytes-per-line)))
  2023.       (declare (type card8 left-pad)
  2024.            (type int16 left-padded-src-x)
  2025.            (type card16 left-padded-width)
  2026.            (type array-index bits-per-line padded-bits-per-line
  2027.              padded-bytes-per-line request-bytes-per-line
  2028.              max-bytes-per-request max-request-height))
  2029.       ;; Be sure that a scanline can fit in a request
  2030.       (when (index-zerop max-request-height)
  2031.         (error "Can't even fit one image scanline in a request"))
  2032.       ;; Be sure a scanline can fit in a buffer
  2033.       (buffer-ensure-size display padded-bytes-per-line)
  2034.       ;; Send the image in multiple requests to avoid exceeding the
  2035.       ;; request limit
  2036.       (do* ((request-src-y src-y (index+ request-src-y request-height))
  2037.         (request-y y (index+ request-y request-height))
  2038.         (height-remaining
  2039.           height (index- height-remaining request-height))
  2040.         (request-height
  2041.           (index-min height-remaining max-request-height)
  2042.           (index-min height-remaining max-request-height)))
  2043.            ((index<= height-remaining 0))
  2044.         (declare (type array-index request-src-y height-remaining
  2045.                request-height))
  2046.         (let* ((request-bytes (index* request-bytes-per-line request-height))
  2047.            (request-words (index-ceiling request-bytes 4))
  2048.            (request-length (index+ request-words 6)))
  2049.           (declare (type array-index request-bytes)
  2050.                (type card16 request-words request-length))
  2051.           (with-buffer-request (display *x-putimage* :gc-force gcontext)
  2052.         ((data (member :bitmap :xy-pixmap :z-pixmap))
  2053.          (cond ((or (eq format :bitmap) bitmap-p) :bitmap)
  2054.                ((plusp left-pad) :xy-pixmap)
  2055.                (t format)))
  2056.         (drawable drawable)
  2057.         (gcontext gcontext)
  2058.         (card16 width request-height)
  2059.         (int16 x request-y)
  2060.         (card8 left-pad depth)
  2061.         (pad16 nil)
  2062.         (progn 
  2063.           (length-put 2 request-length)
  2064.           (setf (buffer-boffset display) (advance-buffer-offset 24))
  2065.           (etypecase image
  2066.             (image-x
  2067.               (ecase (image-x-format (the image-x image))
  2068.             ((:bitmap :xy-pixmap)
  2069.               (write-xy-format-image-x
  2070.                 display image left-padded-src-x request-src-y
  2071.                 left-padded-width request-height
  2072.                 padded-bytes-per-line
  2073.                 unit byte-lsb-first-p bit-lsb-first-p))
  2074.             (:z-pixmap
  2075.               (write-z-format-image-x
  2076.                 display image left-padded-src-x request-src-y
  2077.                 left-padded-width request-height
  2078.                 padded-bytes-per-line
  2079.                 unit byte-lsb-first-p bit-lsb-first-p))))
  2080.             (image-xy
  2081.               (write-image-xy
  2082.             display image left-padded-src-x request-src-y
  2083.             left-padded-width request-height
  2084.             padded-bytes-per-line
  2085.             unit byte-lsb-first-p bit-lsb-first-p))
  2086.             (image-z
  2087.               (write-image-z
  2088.             display image left-padded-src-x request-src-y
  2089.             left-padded-width request-height
  2090.             padded-bytes-per-line
  2091.             unit byte-lsb-first-p bit-lsb-first-p)))
  2092.           ;; Be sure the request is padded to a multiple of 4 bytes
  2093.           (buffer-pad-request display (index- (index* request-words 4) request-bytes))
  2094.           )))))))))
  2095.  
  2096. ;;;-----------------------------------------------------------------------------
  2097. ;;; COPY-IMAGE
  2098.  
  2099. (defun xy-format-image-x->image-x (image x y width height)
  2100.   (declare (type image-x image)
  2101.        (type card16 x y width height)
  2102.        (values image-x))
  2103.   (let* ((padded-x (index+ x (image-x-left-pad image)))
  2104.      (left-pad (index-mod padded-x 8))
  2105.      (x (index- padded-x left-pad))
  2106.      (unit (image-x-unit image))
  2107.      (byte-lsb-first-p (image-x-byte-lsb-first-p image))
  2108.      (bit-lsb-first-p (image-x-bit-lsb-first-p image))
  2109.      (pad (image-x-pad image))
  2110.      (padded-width
  2111.        (index* (index-ceiling (index+ width left-pad) pad) pad))
  2112.      (padded-bytes-per-line (index-ceiling padded-width 8))
  2113.      (padded-bytes-per-plane (index* padded-bytes-per-line height))
  2114.      (length (index* padded-bytes-per-plane (image-depth image)))
  2115.      (obuf (make-array length :element-type 'card8)))
  2116.     (declare (type card16 x)
  2117.          (type card8 left-pad)
  2118.          (type (member 8 16 32) unit pad)
  2119.          (type array-index padded-width padded-bytes-per-line
  2120.            padded-bytes-per-plane length)
  2121.          (type buffer-bytes obuf))
  2122.     (dotimes (plane (image-depth image))
  2123.       (let ((data-start
  2124.           (index* (image-x-bytes-per-line image)
  2125.               (image-height image)
  2126.               plane))
  2127.         (obuf-start
  2128.           (index* padded-bytes-per-plane
  2129.               plane)))
  2130.     (declare (type array-index data-start obuf-start))
  2131.     (write-xy-format-image-x-data
  2132.       (image-x-data image) obuf data-start obuf-start
  2133.       x y width height 
  2134.       (image-x-bytes-per-line image) padded-bytes-per-line
  2135.       unit byte-lsb-first-p bit-lsb-first-p
  2136.       unit byte-lsb-first-p bit-lsb-first-p)))
  2137.     (create-image
  2138.       :width width :height height :depth (image-depth image)
  2139.       :data obuf :format (image-x-format image) :bits-per-pixel 1
  2140.       :bytes-per-line padded-bytes-per-line
  2141.       :unit unit :pad pad :left-pad left-pad
  2142.       :byte-lsb-first-p byte-lsb-first-p :bit-lsb-first-p bit-lsb-first-p)))
  2143.  
  2144. (defun z-format-image-x->image-x (image x y width height)
  2145.   (declare (type image-x image)
  2146.        (type card16 x y width height)
  2147.        (values image-x))
  2148.   (let* ((padded-x (index+ x (image-x-left-pad image)))
  2149.      (left-pad
  2150.        (if (index= (image-depth image) 1)
  2151.            (index-mod padded-x 8)
  2152.          0))
  2153.      (x (index- padded-x left-pad))
  2154.      (bits-per-pixel (image-x-bits-per-pixel image))
  2155.      (unit (image-x-unit image))
  2156.      (byte-lsb-first-p (image-x-byte-lsb-first-p image))
  2157.      (bit-lsb-first-p (image-x-bit-lsb-first-p image))
  2158.      (pad (image-x-pad image))
  2159.      (bits-per-line (index* (index+ width left-pad) bits-per-pixel))
  2160.      (padded-bits-per-line (index* (index-ceiling bits-per-line pad) pad))
  2161.      (padded-bytes-per-line (index-ceiling padded-bits-per-line 8))
  2162.      (padded-bytes-per-plane (index* padded-bytes-per-line height))
  2163.      (length (index* padded-bytes-per-plane (image-depth image)))
  2164.      (obuf (make-array length :element-type 'card8)))
  2165.     (declare (type card16 x)
  2166.          (type card8 left-pad)
  2167.          (type (member 8 16 32) unit pad)
  2168.          (type array-index bits-per-pixel padded-bytes-per-line
  2169.            padded-bytes-per-plane length)
  2170.          (type buffer-bytes obuf))
  2171.     (write-z-format-image-x-data
  2172.       (image-x-data image) obuf 0 0
  2173.       x y width height 
  2174.       (image-x-bytes-per-line image) padded-bytes-per-line
  2175.       bits-per-pixel
  2176.       unit byte-lsb-first-p bit-lsb-first-p
  2177.       unit byte-lsb-first-p bit-lsb-first-p)
  2178.     (create-image
  2179.       :width width :height height :depth (image-depth image)
  2180.       :data obuf :format :z-pixmap :bits-per-pixel bits-per-pixel
  2181.       :bytes-per-line padded-bytes-per-line
  2182.       :unit unit :pad pad :left-pad left-pad
  2183.       :byte-lsb-first-p byte-lsb-first-p :bit-lsb-first-p bit-lsb-first-p)))
  2184.  
  2185. (defun image-x->image-x  (image x y width height)
  2186.   (declare (type image-x image)
  2187.        (type card16 x y width height)
  2188.        (values image-x))
  2189.   (ecase (image-x-format image)
  2190.     ((:bitmap :xy-pixmap)
  2191.       (xy-format-image-x->image-x image x y width height))
  2192.     (:z-pixmap
  2193.       (z-format-image-x->image-x image x y width height))))
  2194.  
  2195. (defun image-x->image-xy (image x y width height)
  2196.   (declare (type image-x image)
  2197.        (type card16 x y width height)
  2198.        (values image-xy))
  2199.   (unless (or (eq (image-x-format image) :bitmap)
  2200.           (eq (image-x-format image) :xy-pixmap)
  2201.           (and (eq (image-x-format image) :z-pixmap)
  2202.            (index= (image-depth image) 1)))
  2203.     (error "Format conversion from ~S to ~S not supported"
  2204.        (image-x-format image) :xy-pixmap))
  2205.   (read-image-xy
  2206.     (image-x-data image) 0 (length (image-x-data image)) nil
  2207.     (index+ x (image-x-left-pad image)) y width height
  2208.     (image-depth image) (image-x-bytes-per-line image)
  2209.     (index* (image-x-bytes-per-line image) (image-height image))
  2210.     (image-x-unit image) (image-x-byte-lsb-first-p image)
  2211.     (image-x-bit-lsb-first-p image)))
  2212.  
  2213. (defun image-x->image-z  (image x y width height)
  2214.   (declare (type image-x image)
  2215.        (type card16 x y width height)
  2216.        (values image-z))
  2217.   (unless (or (eq (image-x-format image) :z-pixmap)
  2218.           (eq (image-x-format image) :bitmap)
  2219.           (and (eq (image-x-format image) :xy-pixmap)
  2220.            (index= (image-depth image) 1)))
  2221.     (error "Format conversion from ~S to ~S not supported"
  2222.        (image-x-format image) :z-pixmap))
  2223.   (read-image-z
  2224.     (image-x-data image) 0 (length (image-x-data image)) nil
  2225.     (index+ x (image-x-left-pad image)) y width height
  2226.     (image-depth image) (image-x-bytes-per-line image)
  2227.     (image-x-bits-per-pixel image)
  2228.     (image-x-unit image) (image-x-byte-lsb-first-p image)
  2229.     (image-x-bit-lsb-first-p image)))
  2230.  
  2231. (defun copy-pixarray (array x y width height bits-per-pixel)
  2232.   (declare (type pixarray array)
  2233.        (type card16 x y width height)
  2234.        (type (member 1 4 8 16 24 32) bits-per-pixel))
  2235.   (let* ((bits-per-line (index* bits-per-pixel width))
  2236.      (padded-bits-per-line
  2237.        (index* (index-ceiling bits-per-line *image-pad*) *image-pad*))
  2238.      (padded-width (index-ceiling padded-bits-per-line bits-per-pixel))
  2239.      (copy (make-array (list height padded-width)
  2240.                :element-type (array-element-type array))))
  2241.     (declare (type array-index bits-per-line padded-bits-per-line padded-width)
  2242.          (type pixarray copy))
  2243.     #.(declare-buffun)
  2244.     (unless (fast-copy-pixarray array copy x y width height bits-per-pixel)
  2245.       (macrolet
  2246.     ((copy (array-type element-type)
  2247.        `(let ((array array)
  2248.           (copy copy))
  2249.           (declare (type ,array-type array copy))
  2250.           (do* ((dst-y 0 (index1+ dst-y))
  2251.             (src-y y (index1+ src-y)))
  2252.            ((index>= dst-y height))
  2253.         (declare (type card16 dst-y src-y))
  2254.         (do* ((dst-x 0 (index1+ dst-x))
  2255.               (src-x x (index1+ src-x)))
  2256.              ((index>= dst-x width))
  2257.           (declare (type card16 dst-x src-x))
  2258.           (setf (aref copy dst-y dst-x)
  2259.             (the ,element-type
  2260.                  (aref array src-y src-x))))))))
  2261.     (ecase bits-per-pixel
  2262.       (1  (copy pixarray-1  pixarray-1-element-type))
  2263.       (4  (copy pixarray-4  pixarray-4-element-type))
  2264.       (8  (copy pixarray-8  pixarray-8-element-type))
  2265.       (16 (copy pixarray-16 pixarray-16-element-type))
  2266.       (24 (copy pixarray-24 pixarray-24-element-type))
  2267.       (32 (copy pixarray-32 pixarray-32-element-type)))))
  2268.     copy))
  2269.  
  2270. (defun image-xy->image-x (image x y width height)
  2271.   (declare (type image-xy image)
  2272.        (type card16 x y width height)
  2273.        (values image-x))
  2274.   (let* ((padded-bits-per-line
  2275.        (index* (index-ceiling width *image-pad*) *image-pad*))
  2276.      (padded-bytes-per-line (index-ceiling padded-bits-per-line 8))
  2277.      (padded-bytes-per-plane (index* padded-bytes-per-line height))
  2278.      (bytes-total (index* padded-bytes-per-plane (image-depth image)))
  2279.      (data (make-array bytes-total :element-type 'card8)))
  2280.     (declare (type array-index padded-bits-per-line padded-bytes-per-line
  2281.            padded-bytes-per-plane bytes-total)
  2282.          (type buffer-bytes data))
  2283.     (let ((index 0))
  2284.       (declare (type array-index index))
  2285.       (dolist (bitmap (image-xy-bitmap-list image))
  2286.     (declare (type pixarray-1 bitmap))
  2287.     (write-pixarray
  2288.       data index bitmap x y width height padded-bytes-per-line 1
  2289.       *image-unit* *image-byte-lsb-first-p* *image-bit-lsb-first-p*)
  2290.     (index-incf index padded-bytes-per-plane)))
  2291.     (create-image
  2292.       :width width :height height :depth (image-depth image)
  2293.       :data data :format :xy-pixmap :bits-per-pixel 1
  2294.       :bytes-per-line padded-bytes-per-line
  2295.       :unit *image-unit* :pad *image-pad*
  2296.       :byte-lsb-first-p *image-byte-lsb-first-p*
  2297.       :bit-lsb-first-p *image-bit-lsb-first-p*)))
  2298.  
  2299. (defun image-xy->image-xy (image x y width height)
  2300.   (declare (type image-xy image)
  2301.        (type card16 x y width height)
  2302.        (values image-xy))
  2303.   (create-image
  2304.     :width width :height height :depth (image-depth image)
  2305.     :data (mapcar
  2306.         #'(lambda (array)
  2307.         (declare (type pixarray-1 array))
  2308.         (copy-pixarray array x y width height 1))
  2309.         (image-xy-bitmap-list image))))
  2310.  
  2311. (defun image-xy->image-z (image x y width height)
  2312.   (declare (type image-z image)
  2313.        (type card16 x y width height)
  2314.        (ignore image x y width height))
  2315.   (error "Format conversion from ~S to ~S not supported"
  2316.      :xy-pixmap :z-pixmap))
  2317.  
  2318. (defun image-z->image-x (image x y width height)
  2319.   (declare (type image-z image)
  2320.        (type card16 x y width height)
  2321.        (values image-x))
  2322.   (let* ((bits-per-line (index* width (image-z-bits-per-pixel image)))
  2323.      (padded-bits-per-line
  2324.        (index* (index-ceiling bits-per-line *image-pad*) *image-pad*))
  2325.      (padded-bytes-per-line (index-ceiling padded-bits-per-line 8))
  2326.      (bytes-total
  2327.        (index* padded-bytes-per-line height (image-depth image)))
  2328.      (data (make-array bytes-total :element-type 'card8))
  2329.      (bits-per-pixel (image-z-bits-per-pixel image)))
  2330.     (declare (type array-index bits-per-line padded-bits-per-line
  2331.            padded-bytes-per-line bytes-total)
  2332.          (type buffer-bytes data)
  2333.          (type (member 1 4 8 16 24 32) bits-per-pixel))
  2334.     (write-pixarray
  2335.       data 0 (image-z-pixarray image) x y width height padded-bytes-per-line 
  2336.       (image-z-bits-per-pixel image)
  2337.       *image-unit* *image-byte-lsb-first-p* *image-bit-lsb-first-p*)
  2338.     (create-image
  2339.       :width width :height height :depth (image-depth image)
  2340.       :data data :format :z-pixmap
  2341.       :bits-per-pixel bits-per-pixel
  2342.       :bytes-per-line padded-bytes-per-line
  2343.       :unit *image-unit* :pad *image-pad*
  2344.       :byte-lsb-first-p *image-byte-lsb-first-p*
  2345.       :bit-lsb-first-p *image-bit-lsb-first-p*)))
  2346.  
  2347. (defun image-z->image-xy (image x y width height)
  2348.   (declare (type image-z image)
  2349.        (type card16 x y width height)
  2350.        (ignore image x y width height))
  2351.   (error "Format conversion from ~S to ~S not supported"
  2352.      :z-pixmap :xy-pixmap))
  2353.  
  2354. (defun image-z->image-z (image x y width height)
  2355.   (declare (type image-z image)
  2356.        (type card16 x y width height)
  2357.        (values image-z))
  2358.   (create-image
  2359.     :width width :height height :depth (image-depth image)
  2360.     :data (copy-pixarray
  2361.         (image-z-pixarray image) x y width height
  2362.         (image-z-bits-per-pixel image))))
  2363.  
  2364. (defun copy-image (image &key (x 0) (y 0) width height result-type)
  2365.   ;; Copy with optional sub-imaging and format conversion.
  2366.   ;; result-type defaults to (type-of image)
  2367.   (declare (type image image)
  2368.        (type card16 x y)
  2369.        (type (or null card16) width height) ;; Default from image
  2370.        (type (or null (member image-x image-xy image-z)) result-type))
  2371.   (declare (values image))
  2372.   (let* ((image-width (image-width image))
  2373.      (image-height (image-height image))
  2374.      (width (or width image-width))
  2375.      (height (or height image-height)))
  2376.     (declare (type card16 image-width image-height width height))
  2377.     (unless (index<= 0 x (index1- image-width)) (error "x not inside image"))
  2378.     (unless (index<= 0 y (index1- image-height)) (error "y not inside image"))
  2379.     (setq width (index-min width (index-max (index- image-width x) 0)))
  2380.     (setq height (index-min height (index-max (index- image-height y) 0)))
  2381.     (let ((copy
  2382.         (etypecase image
  2383.           (image-x
  2384.         (ecase result-type
  2385.           ((nil image-x) (image-x->image-x image x y width height))
  2386.           (image-xy (image-x->image-xy image x y width height))
  2387.           (image-z  (image-x->image-z  image x y width height))))
  2388.           (image-xy
  2389.         (ecase result-type
  2390.           (image-x (image-xy->image-x image x y width height))
  2391.           ((nil image-xy) (image-xy->image-xy image x y width height))
  2392.           (image-z  (image-xy->image-z image x y width height))))
  2393.           (image-z 
  2394.         (ecase result-type
  2395.           (image-x (image-z->image-x image x y width height))
  2396.           (image-xy  (image-z->image-xy image x y width height))
  2397.           ((nil image-z) (image-z->image-z image x y width height)))))))
  2398.       (declare (type image copy))
  2399.       (setf (image-plist copy) (copy-list (image-plist image)))
  2400.       (when (and (image-x-hot image) (not (index-zerop x)))
  2401.     (setf (image-x-hot copy) (index- (image-x-hot image) x)))
  2402.       (when (and (image-y-hot image) (not (index-zerop y)))
  2403.     (setf (image-y-hot copy) (index- (image-y-hot image) y)))
  2404.       copy)))
  2405.  
  2406.  
  2407. ;;;-----------------------------------------------------------------------------
  2408. ;;; Image I/O functions
  2409.  
  2410.  
  2411. (defun read-bitmap-file (pathname)
  2412.   ;; Creates an image from a C include file in standard X11 format
  2413.   (declare (type (or pathname string stream) pathname))
  2414.   (declare (values image))
  2415.   (with-open-file (fstream pathname :direction :input)
  2416.     (let ((line "")
  2417.       (properties nil)
  2418.       (name nil)
  2419.       (name-end nil))
  2420.       (declare (type string line)
  2421.            (type stringable name)
  2422.            (type list properties))
  2423.       ;; Get properties
  2424.       (loop
  2425.     (setq line (read-line fstream))
  2426.     (unless (char= (aref line 0) #\#) (return))
  2427.     (flet ((read-keyword (line start end)
  2428.          (kintern
  2429.            (substitute
  2430.              #\- #\_
  2431.              (#-excl string-upcase
  2432.               #+excl correct-case
  2433.               (subseq line start end))
  2434.              :test #'char=))))
  2435.       (when (null name)
  2436.         (setq name-end (position #\_ line :test #'char= :from-end t)
  2437.           name (read-keyword line 8 name-end))
  2438.         (unless (eq name :image)
  2439.           (setf (getf properties :name) name)))
  2440.       (let* ((ind-start (index1+ name-end))
  2441.          (ind-end (position #\Space line :test #'char=
  2442.                     :start ind-start))
  2443.          (ind (read-keyword line ind-start ind-end))
  2444.          (val-start (index1+ ind-end))
  2445.          (val (parse-integer line :start val-start)))
  2446.         (setf (getf properties ind) val))))
  2447.       ;; Calculate sizes
  2448.       (multiple-value-bind (width height depth left-pad)
  2449.       (flet ((extract-property (ind &rest default)
  2450.            (prog1 (apply #'getf properties ind default)
  2451.               (remf properties ind))))
  2452.         (values (extract-property :width)
  2453.             (extract-property :height)
  2454.             (extract-property :depth 1)
  2455.             (extract-property :left-pad 0)))
  2456.     (declare (type (or null card16) width height)
  2457.          (type image-depth depth)
  2458.          (type card8 left-pad))
  2459.     (unless (and width height) (error "Not a BITMAP file"))
  2460.     (let* ((bits-per-pixel
  2461.          (cond ((index> depth 24) 32)
  2462.                ((index> depth 16) 24)
  2463.                ((index> depth 8)  16)
  2464.                ((index> depth 4)   8)
  2465.                ((index> depth 1)   4)
  2466.                (t                  1)))
  2467.            (bits-per-line (index* width bits-per-pixel))
  2468.            (bytes-per-line (index-ceiling bits-per-line 8))
  2469.            (padded-bits-per-line
  2470.          (index* (index-ceiling bits-per-line 32) 32))
  2471.            (padded-bytes-per-line
  2472.          (index-ceiling padded-bits-per-line 8))
  2473.            (data (make-array (* padded-bytes-per-line height)
  2474.                  :element-type 'card8))
  2475.            (line-base 0)
  2476.            (byte 0))
  2477.       (declare (type array-index bits-per-line bytes-per-line
  2478.              padded-bits-per-line padded-bytes-per-line
  2479.              line-base byte)
  2480.            (type buffer-bytes data))
  2481.       (with-vector (data buffer-bytes)
  2482.         (flet ((parse-hex (char)
  2483.              (second
  2484.                (assoc char
  2485.                   '((#\0  0) (#\1  1) (#\2  2) (#\3  3)
  2486.                 (#\4  4) (#\5  5) (#\6  6) (#\7  7)
  2487.                 (#\8  8) (#\9  9) (#\a 10) (#\b 11)
  2488.                 (#\c 12) (#\d 13) (#\e 14) (#\f 15))
  2489.                   :test #'char-equal))))
  2490.           (declare (inline parse-hex))
  2491.           ;; Read data
  2492.           ;; Note: using read-line instead of read-char would be 20% faster,
  2493.           ;;       but would cons a lot of garbage...
  2494.           (dotimes (i height)
  2495.         (dotimes (j bytes-per-line)
  2496.           (loop (when (eql (read-char fstream) #\x) (return)))
  2497.           (setf (aref data (index+ line-base byte))
  2498.             (index+ (index-ash (parse-hex (read-char fstream)) 4)
  2499.                 (parse-hex (read-char fstream))))
  2500.           (incf byte))
  2501.         (setq byte 0
  2502.               line-base (index+ line-base padded-bytes-per-line)))))
  2503.       ;; Compensate for left-pad in width and x-hot
  2504.       (index-decf width left-pad)
  2505.       (when (and (getf properties :x-hot) (plusp (getf properties :x-hot)))
  2506.         (index-decf (getf properties :x-hot) left-pad))
  2507.       (create-image
  2508.         :width width :height height
  2509.         :depth depth :bits-per-pixel bits-per-pixel
  2510.         :data data :plist properties :format :z-pixmap
  2511.         :bytes-per-line padded-bytes-per-line
  2512.         :unit 32 :pad 32 :left-pad left-pad
  2513.         :byte-lsb-first-p t :bit-lsb-first-p t))))))
  2514.  
  2515. (defun write-bitmap-file (pathname image &optional name)
  2516.   ;; Writes an image to a C include file in standard X11 format
  2517.   ;; NAME argument used for variable prefixes.  Defaults to "image"
  2518.   (declare (type (or pathname string stream) pathname)
  2519.        (type image image)
  2520.        (type (or null stringable) name))
  2521.   (unless (typep image 'image-x)
  2522.     (setq image (copy-image image :result-type 'image-x)))
  2523.   (let* ((plist (image-plist image))
  2524.      (name (or name (image-name image) 'image))
  2525.      (left-pad (image-x-left-pad image))
  2526.      (width (index+ (image-width image) left-pad))
  2527.      (height (image-height image))
  2528.      (depth
  2529.        (if (eq (image-x-format image) :z-pixmap)
  2530.            (image-depth image)
  2531.          1))
  2532.      (bits-per-pixel (image-x-bits-per-pixel image))
  2533.      (bits-per-line (index* width bits-per-pixel))
  2534.      (bytes-per-line (index-ceiling bits-per-line 8))
  2535.      (last (index* bytes-per-line height))
  2536.      (count 0))
  2537.     (declare (type list plist)
  2538.          (type stringable name)
  2539.          (type card8 left-pad)
  2540.          (type card16 width height)
  2541.          (type (member 1 4 8 16 24 32) bits-per-pixel)
  2542.          (type image-depth depth)
  2543.          (type array-index bits-per-line bytes-per-line count last))
  2544.     ;; Move x-hot by left-pad, if there is an x-hot, so image readers that
  2545.     ;; don't know about left pad get the hot spot in the right place.  We have
  2546.     ;; already increased width by left-pad.
  2547.     (when (getf plist :x-hot)
  2548.       (setq plist (copy-list plist))
  2549.       (index-incf (getf plist :x-hot) left-pad))
  2550.     (with-image-data-buffer (data last)
  2551.       (multiple-value-bind (image-swap-function image-swap-lsb-first-p)
  2552.       (image-swap-function
  2553.         bits-per-pixel
  2554.         (image-x-unit image) (image-x-byte-lsb-first-p image)
  2555.         (image-x-bit-lsb-first-p image) 32 t t)
  2556.     (declare (type symbol image-swap-function)
  2557.          (type boolean image-swap-lsb-first-p))
  2558.     (funcall
  2559.       (symbol-function image-swap-function) (image-x-data image)
  2560.       data 0 0 bytes-per-line (image-x-bytes-per-line image)
  2561.       bytes-per-line height image-swap-lsb-first-p))
  2562.       (with-vector (data buffer-bytes)
  2563.     (setq name (string-downcase (string name)))
  2564.     (with-open-file (fstream pathname :direction :output)
  2565.       (format fstream "#define ~a_width ~d~%" name width)
  2566.       (format fstream "#define ~a_height ~d~%" name height)
  2567.       (unless (= depth 1)
  2568.         (format fstream "#define ~a_depth ~d~%" name depth))
  2569.       (unless (zerop left-pad)
  2570.         (format fstream "#define ~a_left_pad ~d~%" name left-pad))
  2571.       (do ((prop plist (cddr prop)))
  2572.           ((endp prop))
  2573.         (when (and (not (member (car prop) '(:width :height)))
  2574.                (numberp (cadr prop)))
  2575.           (format fstream "#define ~a_~a ~d~%"
  2576.               name
  2577.               (substitute
  2578.             #\_ #\- (string-downcase (string (car prop)))
  2579.             :test #'char=)
  2580.               (cadr prop))))
  2581.       (format fstream "static char ~a_bits[] = {" name)
  2582.       (dotimes (i height)
  2583.         (dotimes (j bytes-per-line)
  2584.           (when (zerop (index-mod count 15))
  2585.         (terpri fstream)
  2586.         (write-char #\space fstream))
  2587.           (write-string "0x" fstream)
  2588.           ;; Faster than (format fstream "0x~2,'0x," byte)
  2589.           (let ((byte (aref data count))
  2590.             (translate "0123456789abcdef"))
  2591.         (declare (type card8 byte))
  2592.         (write-char (char translate (ldb (byte 4 4) byte)) fstream)
  2593.         (write-char (char translate (ldb (byte 4 0) byte)) fstream))
  2594.           (index-incf count)
  2595.           (unless (index= count last)
  2596.         (write-char #\, fstream))))
  2597.       (format fstream "};~%" fstream))))))
  2598.  
  2599. (defun bitmap-image (&optional plist &rest patterns)
  2600.   ;; Create an image containg pattern
  2601.   ;; PATTERNS are bit-vector constants (e.g. #*10101)
  2602.   ;; If the first parameter is a list, its used as the image property-list.
  2603.   (declare (type (or list bit-vector) plist)
  2604.        (type list patterns)) ;; list of bitvector
  2605.   (declare (values image))
  2606.   (unless (listp plist)
  2607.     (push plist patterns)
  2608.     (setq plist nil))
  2609.   (let* ((width (length (first patterns)))
  2610.      (height (length patterns))
  2611.      (bitarray (make-array (list height width) :element-type 'bit))
  2612.      (row 0))
  2613.     (declare (type card16 width height row)
  2614.          (type pixarray-1 bitarray))
  2615.     (dolist (pattern patterns)
  2616.       (declare (type simple-bit-vector pattern))
  2617.       (dotimes (col width)
  2618.     (declare (type card16 col))
  2619.     (setf (aref bitarray row col) (the bit (aref pattern col))))
  2620.       (incf row))
  2621.     (create-image :width width :height height :plist plist :data bitarray)))
  2622.  
  2623. (defun image-pixmap (drawable image &key gcontext width height depth)
  2624.   ;; Create a pixmap containing IMAGE. Size defaults from the image.
  2625.   ;; DEPTH is the pixmap depth.
  2626.   ;; GCONTEXT is used for putting the image into the pixmap.
  2627.   ;; If none is supplied, then one is created, used then freed.
  2628.   (declare (type drawable drawable)
  2629.        (type image image)
  2630.        (type (or null gcontext) gcontext)
  2631.        (type (or null card16) width height)
  2632.        (type (or null card8) depth))
  2633.   (declare (values pixmap))
  2634.   (let* ((image-width (image-width image))
  2635.      (image-height (image-height image))
  2636.      (image-depth (image-depth image))
  2637.      (width (or width image-width))
  2638.      (height (or height image-height))
  2639.      (depth (or depth image-depth))
  2640.      (pixmap (create-pixmap :drawable drawable
  2641.                    :width width
  2642.                    :height height
  2643.                    :depth depth))
  2644.      (gc (or gcontext (create-gcontext
  2645.                 :drawable pixmap
  2646.                 :foreground 1
  2647.                 :background 0))))
  2648.     (unless (= depth image-depth)
  2649.       (if (= image-depth 1)
  2650.       (unless gcontext (xlib::required-arg gcontext))
  2651.     (error "Pixmap depth ~d incompatable with image depth ~d"
  2652.            depth image-depth)))           
  2653.     (put-image pixmap gc image :x 0 :y 0 :bitmap-p (and (= image-depth 1) gcontext))
  2654.     ;; Tile when image-width is less than the pixmap width, or
  2655.     ;; the image-height is less than the pixmap height.
  2656.     ;; ??? Would it be better to create a temporary pixmap and 
  2657.     ;; ??? let the server do the tileing?
  2658.     (do ((x image-width (+ x image-width)))
  2659.     ((>= x width))
  2660.       (copy-area pixmap gc 0 0 image-width image-height pixmap x 0)
  2661.       (incf image-width image-width))
  2662.     (do ((y image-height (+ y image-height)))
  2663.     ((>= y height))
  2664.       (copy-area pixmap gc 0 0 image-width image-height pixmap 0 y)
  2665.       (incf image-height image-height))
  2666.     (unless gcontext (free-gcontext gc))
  2667.     pixmap))
  2668.  
  2669.